Merge "Set WindowSession's touchmode when in local focus mode,"
diff --git a/Android.mk b/Android.mk
index b95ab2e..e94bebb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -42,6 +42,7 @@
 
 # EventLogTags files.
 LOCAL_SRC_FILES += \
+       core/java/android/auditing/SecurityLogTags.logtags \
        core/java/android/content/EventLogTags.logtags \
        core/java/android/speech/tts/EventLogTags.logtags \
        core/java/android/webkit/EventLogTags.logtags \
@@ -96,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 \
@@ -209,6 +211,7 @@
 	core/java/android/os/IBatteryPropertiesRegistrar.aidl \
 	core/java/android/os/ICancellationSignal.aidl \
 	core/java/android/os/IDeviceIdleController.aidl \
+	core/java/android/os/IMaintenanceActivityListener.aidl \
 	core/java/android/os/IMessenger.aidl \
 	core/java/android/os/INetworkActivityListener.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
@@ -341,6 +344,7 @@
 	media/java/android/media/IAudioRoutesObserver.aidl \
 	media/java/android/media/IMediaHTTPConnection.aidl \
 	media/java/android/media/IMediaHTTPService.aidl \
+	media/java/android/media/IMediaResourceMonitor.aidl \
 	media/java/android/media/IMediaRouterClient.aidl \
 	media/java/android/media/IMediaRouterService.aidl \
 	media/java/android/media/IMediaScannerListener.aidl \
@@ -408,10 +412,14 @@
 	telephony/java/com/android/internal/telephony/ISms.aidl \
 	telephony/java/com/android/internal/telephony/ISub.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
+	telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
 	wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl \
+	wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl \
+	wifi/java/android/net/wifi/nan/IWifiNanManager.aidl \
+	wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
 	wifi/java/android/net/wifi/IWifiScanner.aidl \
 	wifi/java/android/net/wifi/IRttManager.aidl \
@@ -422,7 +430,9 @@
 	core/java/android/service/quicksettings/IQSTileService.aidl \
 
 # FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
-LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
+LOCAL_AIDL_INCLUDES += \
+      $(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
+      frameworks/native/aidl/binder
 
 LOCAL_INTERMEDIATE_SOURCES := \
 			$(framework_res_source_path)/android/R.java \
@@ -480,6 +490,11 @@
 	frameworks/base/media/java/android/media/tv/TvTrackInfo.aidl \
 	frameworks/base/media/java/android/media/browse/MediaBrowser.aidl \
 	frameworks/base/wifi/java/android/net/wifi/ScanSettings.aidl \
+	frameworks/base/wifi/java/android/net/wifi/nan/ConfigRequest.aidl \
+	frameworks/base/wifi/java/android/net/wifi/nan/PublishData.aidl \
+	frameworks/base/wifi/java/android/net/wifi/nan/SubscribeData.aidl \
+	frameworks/base/wifi/java/android/net/wifi/nan/PublishSettings.aidl \
+	frameworks/base/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl \
@@ -522,7 +537,6 @@
 	frameworks/base/core/java/android/os/ParcelUuid.aidl \
 	frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
 	frameworks/base/core/java/android/os/ResultReceiver.aidl \
-	frameworks/base/core/java/android/os/PersistableBundle.aidl \
 	frameworks/base/core/java/android/os/WorkSource.aidl \
 	frameworks/base/core/java/android/os/DropBoxManager.aidl \
 	frameworks/base/core/java/android/os/Bundle.aidl \
@@ -630,6 +644,7 @@
 	frameworks/base/core/java/android/bluetooth/BluetoothDevice.aidl \
 	frameworks/base/core/java/android/database/CursorWindow.aidl \
 	frameworks/base/core/java/android/service/quicksettings/Tile.aidl \
+	frameworks/native/aidl/binder/android/os/PersistableBundle.aidl \
 
 gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
 $(gen): PRIVATE_SRC_FILES := $(aidl_files)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 40908f1..2fe5cbe 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -238,6 +238,8 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/DocumentsUI_intermediates)
 $(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IRemoteControlClient.*)
 $(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IRemoteControlDisplay.*)
+$(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit1_intermediates/src/com/android/test/split/feature/R.java)
+$(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit2_intermediates/src/com/android/test/split/feature/R.java)
 
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
diff --git a/api/current.txt b/api/current.txt
index 629d832..e347c4c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -524,6 +524,7 @@
     field public static final int expandableListViewStyle = 16842863; // 0x101006f
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
+    field public static final int externalService = 16844047; // 0x101050f
     field public static final int extraTension = 16843371; // 0x101026b
     field public static final int extractNativeLibs = 16844010; // 0x10104ea
     field public static final int factor = 16843219; // 0x10101d3
@@ -2611,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();
@@ -2750,15 +2752,12 @@
     method public android.os.Bundle addAccountFromCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public abstract android.os.Bundle confirmCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public abstract android.os.Bundle editProperties(android.accounts.AccountAuthenticatorResponse, java.lang.String);
-    method public android.os.Bundle finishSession(android.accounts.AccountAuthenticatorResponse, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public android.os.Bundle getAccountCredentialsForCloning(android.accounts.AccountAuthenticatorResponse, android.accounts.Account) throws android.accounts.NetworkErrorException;
     method public android.os.Bundle getAccountRemovalAllowed(android.accounts.AccountAuthenticatorResponse, android.accounts.Account) throws android.accounts.NetworkErrorException;
     method public abstract android.os.Bundle getAuthToken(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
     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 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;
     field public static final java.lang.String KEY_CUSTOM_TOKEN_EXPIRY = "android.accounts.expiry";
   }
@@ -2796,7 +2795,6 @@
     method public void clearPassword(android.accounts.Account);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> confirmCredentials(android.accounts.Account, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
-    method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public static android.accounts.AccountManager get(android.content.Context);
     method public android.accounts.Account[] getAccounts();
     method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -2824,8 +2822,6 @@
     method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
     method public void setPassword(android.accounts.Account, java.lang.String);
     method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
-    method public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
-    method public android.accounts.AccountManagerFuture<android.os.Bundle> startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator";
     field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
@@ -2842,8 +2838,6 @@
     field public static final java.lang.String KEY_ACCOUNT_AUTHENTICATOR_RESPONSE = "accountAuthenticatorResponse";
     field public static final java.lang.String KEY_ACCOUNT_MANAGER_RESPONSE = "accountManagerResponse";
     field public static final java.lang.String KEY_ACCOUNT_NAME = "authAccount";
-    field public static final java.lang.String KEY_ACCOUNT_SESSION_BUNDLE = "accountSessionBundle";
-    field public static final java.lang.String KEY_ACCOUNT_STATUS_TOKEN = "accountStatusToken";
     field public static final java.lang.String KEY_ACCOUNT_TYPE = "accountType";
     field public static final java.lang.String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
     field public static final java.lang.String KEY_AUTHENTICATOR_TYPES = "authenticator_types";
@@ -3505,6 +3499,7 @@
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
     method public void onProvideAssistContent(android.app.assist.AssistContent);
     method public void onProvideAssistData(android.os.Bundle);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public android.net.Uri onProvideReferrer();
     method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
     method protected void onRestart();
@@ -4189,6 +4184,7 @@
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPrepareOptionsMenu(android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public void onRestoreInstanceState(android.os.Bundle);
     method public android.os.Bundle onSaveInstanceState();
     method public boolean onSearchRequested(android.view.SearchEvent);
@@ -5742,6 +5738,9 @@
     ctor public DeviceAdminReceiver();
     method public android.app.admin.DevicePolicyManager getManager(android.content.Context);
     method public android.content.ComponentName getWho(android.content.Context);
+    method public void onBugreportFailed(android.content.Context, android.content.Intent, int);
+    method public void onBugreportShared(android.content.Context, android.content.Intent, java.lang.String);
+    method public void onBugreportSharingDeclined(android.content.Context, android.content.Intent);
     method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, android.net.Uri, java.lang.String);
     method public java.lang.CharSequence onDisableRequested(android.content.Context, android.content.Intent);
     method public void onDisabled(android.content.Context, android.content.Intent);
@@ -5766,11 +5765,16 @@
     field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
     field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
     field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE";
+    field public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0; // 0x0
+    field public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1; // 0x1
     field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
     field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
     field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
   }
 
+  public static abstract class DeviceAdminReceiver.BugreportFailureCode implements java.lang.annotation.Annotation {
+  }
+
   public class DevicePolicyManager {
     method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5786,6 +5790,7 @@
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
     method public java.lang.String[] getAccountTypesWithManagementDisabled();
     method public java.util.List<android.content.ComponentName> getActiveAdmins();
+    method public java.lang.String getAlwaysOnVpnPackage(android.content.ComponentName);
     method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
     method public java.lang.String getApplicationRestrictionsManagingPackage(android.content.ComponentName);
     method public boolean getAutoTimeRequired();
@@ -5848,8 +5853,10 @@
     method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public boolean removeKeyPair(android.content.ComponentName, java.lang.String);
     method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
+    method public boolean requestBugreport(android.content.ComponentName);
     method public boolean resetPassword(java.lang.String, int);
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
+    method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String);
     method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
     method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void setApplicationRestrictionsManagingPackage(android.content.ComponentName, java.lang.String);
@@ -5905,6 +5912,7 @@
     field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_DEVICE = "android.app.action.PROVISION_MANAGED_DEVICE";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
+    field public static final java.lang.String ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = "android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD";
     field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
     field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
     field public static final java.lang.String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
@@ -6470,6 +6478,30 @@
 
 }
 
+package android.auditing {
+
+  public class SecurityLog {
+    ctor public SecurityLog();
+    field public static final int TAG_ADB_SHELL_CMD = 210002; // 0x33452
+    field public static final int TAG_ADB_SHELL_INTERACTIVE = 210001; // 0x33451
+    field public static final int TAG_APP_PROCESS_START = 210005; // 0x33455
+    field public static final int TAG_DEVICE_LOCKED = 210007; // 0x33457
+    field public static final int TAG_DEVICE_UNLOCK_ATTEMPT = 210006; // 0x33456
+    field public static final int TAG_SYNC_RECV_FILE = 210003; // 0x33453
+    field public static final int TAG_SYNC_SEND_FILE = 210004; // 0x33454
+  }
+
+  public static class SecurityLog.SecurityEvent implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.Object getData();
+    method public int getTag();
+    method public long getTimeNanos();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.auditing.SecurityLog.SecurityEvent> CREATOR;
+  }
+
+}
+
 package android.bluetooth {
 
   public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
@@ -7203,6 +7235,15 @@
     field public static final int TYPE_SCO = 2; // 0x2
   }
 
+  public class OobData implements android.os.Parcelable {
+    ctor public OobData();
+    method public int describeContents();
+    method public byte[] getSecurityManagerTk();
+    method public void setSecurityManagerTk(byte[]);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR;
+  }
+
 }
 
 package android.bluetooth.le {
@@ -8386,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";
@@ -9292,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);
@@ -9308,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 {
@@ -19358,6 +19404,7 @@
     field public static final deprecated int NUM_STREAMS = 5; // 0x5
     field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
     field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+    field public static final java.lang.String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED = "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
     field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
     field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
     field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
@@ -19395,9 +19442,10 @@
     method public abstract void onAudioFocusChange(int);
   }
 
-  public class AudioRecord {
+  public class AudioRecord implements android.media.AudioRouting {
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
-    method public void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -19421,7 +19469,8 @@
     method public int read(java.nio.ByteBuffer, int);
     method public int read(java.nio.ByteBuffer, int, int);
     method public void release();
-    method public void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
+    method public deprecated void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
+    method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
     method public int setNotificationMarkerPosition(int);
     method public int setPositionNotificationPeriod(int);
     method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
@@ -19459,17 +19508,29 @@
     method public abstract void onRoutingChanged(android.media.AudioRecord);
   }
 
+  public abstract interface AudioRouting {
+    method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
+    method public abstract android.media.AudioDeviceInfo getPreferredDevice();
+    method public abstract void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
+    method public abstract boolean setPreferredDevice(android.media.AudioDeviceInfo);
+  }
+
+  public static abstract interface AudioRouting.OnRoutingChangedListener {
+    method public abstract void onRoutingChanged(android.media.AudioRouting);
+  }
+
   public final class AudioTimestamp {
     ctor public AudioTimestamp();
     field public long framePosition;
     field public long nanoTime;
   }
 
-  public class AudioTrack {
+  public class AudioTrack implements android.media.AudioRouting {
     ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
-    method public void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
+    method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
+    method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public void flush();
     method public int getAudioFormat();
@@ -19499,7 +19560,8 @@
     method public void play() throws java.lang.IllegalStateException;
     method public void release();
     method public int reloadStaticData();
-    method public void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
+    method public deprecated void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
+    method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
     method public int setAuxEffectSendLevel(float);
     method public int setLoopPoints(int, int, int);
     method public int setNotificationMarkerPosition(int);
@@ -19552,8 +19614,8 @@
     method public abstract void onPeriodicNotification(android.media.AudioTrack);
   }
 
-  public static abstract interface AudioTrack.OnRoutingChangedListener {
-    method public abstract void onRoutingChanged(android.media.AudioTrack);
+  public static abstract deprecated interface AudioTrack.OnRoutingChangedListener {
+    method public abstract deprecated void onRoutingChanged(android.media.AudioTrack);
   }
 
   public class CamcorderProfile {
@@ -20371,6 +20433,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";
@@ -20703,6 +20766,7 @@
     field public static final int DEFAULT = 0; // 0x0
     field public static final int MIC = 1; // 0x1
     field public static final int REMOTE_SUBMIX = 8; // 0x8
+    field public static final int UNPROCESSED = 9; // 0x9
     field public static final int VOICE_CALL = 4; // 0x4
     field public static final int VOICE_COMMUNICATION = 7; // 0x7
     field public static final int VOICE_DOWNLINK = 3; // 0x3
@@ -22467,6 +22531,7 @@
     field public static final int FORMAT_AUDIBLE = 47364; // 0xb904
     field public static final int FORMAT_AVI = 12298; // 0x300a
     field public static final int FORMAT_BMP = 14340; // 0x3804
+    field public static final int FORMAT_DNG = 14353; // 0x3811
     field public static final int FORMAT_DPOF = 12294; // 0x3006
     field public static final int FORMAT_EXECUTABLE = 12291; // 0x3003
     field public static final int FORMAT_EXIF_JPEG = 14337; // 0x3801
@@ -22557,7 +22622,7 @@
     method public int[] getObjectHandles(int, int, int);
     method public android.mtp.MtpObjectInfo getObjectInfo(int);
     method public long getParent(int);
-    method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+    method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
     method public long getStorageId(int);
     method public int[] getStorageIds();
     method public android.mtp.MtpStorageInfo getStorageInfo(int);
@@ -24240,6 +24305,7 @@
 
   public final class Tag implements android.os.Parcelable {
     method public int describeContents();
+    method public boolean done(int);
     method public byte[] getId();
     method public java.lang.String[] getTechList();
     method public void writeToParcel(android.os.Parcel, int);
@@ -28472,6 +28538,7 @@
   }
 
   public class UserManager {
+    method public static android.content.Intent createUserCreationIntent(java.lang.String, java.lang.String, java.lang.String, android.os.PersistableBundle);
     method public android.os.Bundle getApplicationRestrictions(java.lang.String);
     method public long getSerialNumberForUser(android.os.UserHandle);
     method public int getUserCount();
@@ -29381,6 +29448,22 @@
     field public static final java.lang.String _ID = "_id";
   }
 
+  public class BlockedNumberContract {
+    method public static boolean isBlocked(android.content.Context, java.lang.String);
+    field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
+    field public static final android.net.Uri AUTHORITY_URI;
+  }
+
+  public static class BlockedNumberContract.BlockedNumbers {
+    field public static final java.lang.String COLUMN_E164_NUMBER = "e164_number";
+    field public static final java.lang.String COLUMN_ID = "_id";
+    field public static final java.lang.String COLUMN_ORIGINAL_NUMBER = "original_number";
+    field public static final java.lang.String COLUMN_STRIPPED_NUMBER = "stripped_number";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
   public class Browser {
     ctor public Browser();
     method public static final void sendString(android.content.Context, java.lang.String);
@@ -33502,6 +33585,7 @@
     method public boolean onMenuOpened(int, android.view.Menu);
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -33596,6 +33680,7 @@
     method public abstract void onUnsubscribe(android.net.Uri);
     field public static final java.lang.String EXTRA_RULE_ID = "android.content.automatic.ruleId";
     field public static final java.lang.String META_DATA_CONFIGURATION_ACTIVITY = "android.service.zen.automatic.configurationActivity";
+    field public static final java.lang.String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit";
     field public static final java.lang.String META_DATA_RULE_TYPE = "android.service.zen.automatic.ruleType";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
   }
@@ -33723,17 +33808,24 @@
     method public java.lang.CharSequence getContentDescription();
     method public android.graphics.drawable.Icon getIcon();
     method public java.lang.CharSequence getLabel();
+    method public int getState();
     method public void setContentDescription(java.lang.CharSequence);
     method public void setIcon(android.graphics.drawable.Icon);
     method public void setLabel(java.lang.CharSequence);
+    method public void setState(int);
     method public void updateTile();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.quicksettings.Tile> CREATOR;
+    field public static final int STATE_ACTIVE = 2; // 0x2
+    field public static final int STATE_INACTIVE = 1; // 0x1
+    field public static final int STATE_UNAVAILABLE = 0; // 0x0
   }
 
   public class TileService extends android.app.Service {
     ctor public TileService();
     method public final android.service.quicksettings.Tile getQsTile();
+    method public final boolean isLocked();
+    method public final boolean isSecure();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onClick();
     method public void onStartListening();
@@ -33742,6 +33834,8 @@
     method public void onTileRemoved();
     method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
     method public final void showDialog(android.app.Dialog);
+    method public final void startActivityAndCollapse(android.content.Intent);
+    method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
     field public static final int TILE_MODE_ACTIVE = 2; // 0x2
     field public static final int TILE_MODE_PASSIVE = 1; // 0x1
@@ -35570,12 +35664,24 @@
     method public android.os.PersistableBundle getConfigForSubId(int);
     method public void notifyConfigChangedForSubId(int);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+    field public static final java.lang.String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS = "bool_allow_emergency_video_calls";
+    field public static final java.lang.String BOOL_ALLOW_VIDEO_PAUSE = "bool_allow_video_pause";
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
+    field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final java.lang.String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool";
     field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool";
+    field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool";
+    field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool";
     field public static final java.lang.String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
     field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
     field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
+    field public static final java.lang.String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool";
+    field public static final java.lang.String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL = "carrier_ims_gba_required_bool";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL = "carrier_instant_lettering_available_bool";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING = "carrier_instant_lettering_encoding_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING = "carrier_instant_lettering_escaped_chars_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING = "carrier_instant_lettering_invalid_chars_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_LENGTH_LIMIT_INT = "carrier_instant_lettering_length_limit_int";
     field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
     field public static final java.lang.String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
@@ -35584,20 +35690,30 @@
     field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
     field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
     field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
+    field public static final java.lang.String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
     field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_BOOL = "ci_action_on_sys_update_bool";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING = "ci_action_on_sys_update_extra_string";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING = "ci_action_on_sys_update_intent_string";
     field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
     field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
     field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
     field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
+    field public static final java.lang.String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
     field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
+    field public static final java.lang.String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
     field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
+    field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
     field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
     field public static final java.lang.String KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL = "ignore_sim_network_locked_events_bool";
+    field public static final java.lang.String KEY_IMS_DTMF_TONE_DELAY_INT = "ims_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
     field public static final java.lang.String KEY_MMS_ALIAS_MAX_CHARS_INT = "aliasMaxChars";
     field public static final java.lang.String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars";
@@ -35631,14 +35747,17 @@
     field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
     field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
     field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
+    field public static final java.lang.String KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
     field public static final java.lang.String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
     field public static final java.lang.String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
     field public static final java.lang.String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool";
     field public static final java.lang.String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
+    field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
     field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
     field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
     field public static final java.lang.String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool";
     field public static final java.lang.String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
+    field public static final java.lang.String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool";
     field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
     field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
     field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
@@ -36132,6 +36251,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();
@@ -38098,9 +38218,11 @@
 
   public class LocaleSpan extends android.text.style.MetricAffectingSpan implements android.text.ParcelableSpan {
     ctor public LocaleSpan(java.util.Locale);
+    ctor public LocaleSpan(android.util.LocaleList);
     ctor public LocaleSpan(android.os.Parcel);
     method public int describeContents();
     method public java.util.Locale getLocale();
+    method public android.util.LocaleList getLocales();
     method public int getSpanTypeId();
     method public void updateDrawState(android.text.TextPaint);
     method public void updateMeasureState(android.text.TextPaint);
@@ -38206,7 +38328,8 @@
     ctor public SuggestionSpan(android.os.Parcel);
     method public int describeContents();
     method public int getFlags();
-    method public java.lang.String getLocale();
+    method public deprecated java.lang.String getLocale();
+    method public java.util.Locale getLocaleObject();
     method public int getSpanTypeId();
     method public java.lang.String[] getSuggestions();
     method public void setFlags(int);
@@ -40390,6 +40513,27 @@
     method public void startTracking(android.view.KeyEvent, java.lang.Object);
   }
 
+  public final class KeyboardShortcutGroup implements android.os.Parcelable {
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>);
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence);
+    method public void addItem(android.view.KeyboardShortcutInfo);
+    method public int describeContents();
+    method public java.util.List<android.view.KeyboardShortcutInfo> getItems();
+    method public java.lang.CharSequence getLabel();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutGroup> CREATOR;
+  }
+
+  public final class KeyboardShortcutInfo implements android.os.Parcelable {
+    ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
+    method public int describeContents();
+    method public char getBaseCharacter();
+    method public java.lang.CharSequence getLabel();
+    method public int getModifiers();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutInfo> CREATOR;
+  }
+
   public abstract class LayoutInflater {
     ctor protected LayoutInflater(android.content.Context);
     ctor protected LayoutInflater(android.view.LayoutInflater, android.content.Context);
@@ -42391,6 +42535,7 @@
     method public abstract boolean onMenuOpened(int, android.view.Menu);
     method public abstract void onPanelClosed(int, android.view.Menu);
     method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public abstract void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public abstract boolean onSearchRequested();
     method public abstract boolean onSearchRequested(android.view.SearchEvent);
     method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -42716,6 +42861,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();
@@ -42778,6 +42924,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);
@@ -43334,6 +43481,7 @@
     method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public boolean commitText(java.lang.CharSequence, int);
     method public boolean deleteSurroundingText(int, int);
+    method public boolean deleteSurroundingTextInCodePoints(int, int);
     method public boolean endBatchEdit();
     method public boolean finishComposingText();
     method public static int getComposingSpanEnd(android.text.Spannable);
@@ -43499,6 +43647,7 @@
     method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public abstract boolean commitText(java.lang.CharSequence, int);
     method public abstract boolean deleteSurroundingText(int, int);
+    method public abstract boolean deleteSurroundingTextInCodePoints(int, int);
     method public abstract boolean endBatchEdit();
     method public abstract boolean finishComposingText();
     method public abstract int getCursorCapsMode(int);
@@ -43529,6 +43678,7 @@
     method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public boolean commitText(java.lang.CharSequence, int);
     method public boolean deleteSurroundingText(int, int);
+    method public boolean deleteSurroundingTextInCodePoints(int, int);
     method public boolean endBatchEdit();
     method public boolean finishComposingText();
     method public int getCursorCapsMode(int);
@@ -43591,6 +43741,7 @@
   }
 
   public final class InputMethodManager {
+    method public void dispatchKeyEventFromInputMethod(android.view.View, android.view.KeyEvent);
     method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]);
     method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype();
     method public java.util.List<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList();
@@ -45561,6 +45712,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 6a36ce0..1a76097 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -619,6 +619,7 @@
     field public static final int expandableListViewStyle = 16842863; // 0x101006f
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
+    field public static final int externalService = 16844047; // 0x101050f
     field public static final int extraTension = 16843371; // 0x101026b
     field public static final int extractNativeLibs = 16844010; // 0x10104ea
     field public static final int factor = 16843219; // 0x10101d3
@@ -2713,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();
@@ -2859,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;
@@ -2914,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);
@@ -3611,6 +3615,7 @@
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
     method public void onProvideAssistContent(android.app.assist.AssistContent);
     method public void onProvideAssistData(android.os.Bundle);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public android.net.Uri onProvideReferrer();
     method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
     method protected void onRestart();
@@ -4310,6 +4315,7 @@
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPrepareOptionsMenu(android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public void onRestoreInstanceState(android.os.Bundle);
     method public android.os.Bundle onSaveInstanceState();
     method public boolean onSearchRequested(android.view.SearchEvent);
@@ -5867,6 +5873,9 @@
     ctor public DeviceAdminReceiver();
     method public android.app.admin.DevicePolicyManager getManager(android.content.Context);
     method public android.content.ComponentName getWho(android.content.Context);
+    method public void onBugreportFailed(android.content.Context, android.content.Intent, int);
+    method public void onBugreportShared(android.content.Context, android.content.Intent, java.lang.String);
+    method public void onBugreportSharingDeclined(android.content.Context, android.content.Intent);
     method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, android.net.Uri, java.lang.String);
     method public java.lang.CharSequence onDisableRequested(android.content.Context, android.content.Intent);
     method public void onDisabled(android.content.Context, android.content.Intent);
@@ -5891,11 +5900,16 @@
     field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
     field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
     field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE";
+    field public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0; // 0x0
+    field public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1; // 0x1
     field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
     field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
     field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
   }
 
+  public static abstract class DeviceAdminReceiver.BugreportFailureCode implements java.lang.annotation.Annotation {
+  }
+
   public class DevicePolicyManager {
     method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5912,6 +5926,7 @@
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
     method public java.lang.String[] getAccountTypesWithManagementDisabled();
     method public java.util.List<android.content.ComponentName> getActiveAdmins();
+    method public java.lang.String getAlwaysOnVpnPackage(android.content.ComponentName);
     method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
     method public java.lang.String getApplicationRestrictionsManagingPackage(android.content.ComponentName);
     method public boolean getAutoTimeRequired();
@@ -5982,9 +5997,11 @@
     method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public boolean removeKeyPair(android.content.ComponentName, java.lang.String);
     method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
+    method public boolean requestBugreport(android.content.ComponentName);
     method public boolean resetPassword(java.lang.String, int);
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
     method public deprecated boolean setActiveProfileOwner(android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException;
+    method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String);
     method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
     method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void setApplicationRestrictionsManagingPackage(android.content.ComponentName, java.lang.String);
@@ -6040,6 +6057,7 @@
     field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_DEVICE = "android.app.action.PROVISION_MANAGED_DEVICE";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
+    field public static final java.lang.String ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = "android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD";
     field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
     field public static final java.lang.String ACTION_SET_PROFILE_OWNER = "android.app.action.SET_PROFILE_OWNER";
     field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
@@ -6276,10 +6294,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 {
@@ -6302,7 +6343,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();
@@ -6311,6 +6354,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
@@ -6686,6 +6730,30 @@
 
 }
 
+package android.auditing {
+
+  public class SecurityLog {
+    ctor public SecurityLog();
+    field public static final int TAG_ADB_SHELL_CMD = 210002; // 0x33452
+    field public static final int TAG_ADB_SHELL_INTERACTIVE = 210001; // 0x33451
+    field public static final int TAG_APP_PROCESS_START = 210005; // 0x33455
+    field public static final int TAG_DEVICE_LOCKED = 210007; // 0x33457
+    field public static final int TAG_DEVICE_UNLOCK_ATTEMPT = 210006; // 0x33456
+    field public static final int TAG_SYNC_RECV_FILE = 210003; // 0x33453
+    field public static final int TAG_SYNC_SEND_FILE = 210004; // 0x33454
+  }
+
+  public static class SecurityLog.SecurityEvent implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.Object getData();
+    method public int getTag();
+    method public long getTimeNanos();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.auditing.SecurityLog.SecurityEvent> CREATOR;
+  }
+
+}
+
 package android.bluetooth {
 
   public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
@@ -7427,6 +7495,15 @@
     field public static final int TYPE_SCO = 2; // 0x2
   }
 
+  public class OobData implements android.os.Parcelable {
+    ctor public OobData();
+    method public int describeContents();
+    method public byte[] getSecurityManagerTk();
+    method public void setSecurityManagerTk(byte[]);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR;
+  }
+
 }
 
 package android.bluetooth.le {
@@ -8204,6 +8281,7 @@
     field public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; // 0x10
     field public static final int BIND_AUTO_CREATE = 1; // 0x1
     field public static final int BIND_DEBUG_UNBIND = 2; // 0x2
+    field public static final int BIND_EXTERNAL_SERVICE = -2147483648; // 0x80000000
     field public static final int BIND_IMPORTANT = 64; // 0x40
     field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
     field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
@@ -8647,6 +8725,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";
@@ -9592,6 +9672,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);
@@ -9608,7 +9689,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 {
@@ -20654,6 +20737,7 @@
     field public static final deprecated int NUM_STREAMS = 5; // 0x5
     field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
     field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+    field public static final java.lang.String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED = "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
     field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
     field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
     field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
@@ -20691,10 +20775,11 @@
     method public abstract void onAudioFocusChange(int);
   }
 
-  public class AudioRecord {
+  public class AudioRecord implements android.media.AudioRouting {
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioRecord(android.media.AudioAttributes, android.media.AudioFormat, int, int) throws java.lang.IllegalArgumentException;
-    method public void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -20718,7 +20803,8 @@
     method public int read(java.nio.ByteBuffer, int);
     method public int read(java.nio.ByteBuffer, int, int);
     method public void release();
-    method public void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
+    method public deprecated void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
+    method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
     method public int setNotificationMarkerPosition(int);
     method public int setPositionNotificationPeriod(int);
     method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
@@ -20758,17 +20844,29 @@
     method public abstract void onRoutingChanged(android.media.AudioRecord);
   }
 
+  public abstract interface AudioRouting {
+    method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
+    method public abstract android.media.AudioDeviceInfo getPreferredDevice();
+    method public abstract void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
+    method public abstract boolean setPreferredDevice(android.media.AudioDeviceInfo);
+  }
+
+  public static abstract interface AudioRouting.OnRoutingChangedListener {
+    method public abstract void onRoutingChanged(android.media.AudioRouting);
+  }
+
   public final class AudioTimestamp {
     ctor public AudioTimestamp();
     field public long framePosition;
     field public long nanoTime;
   }
 
-  public class AudioTrack {
+  public class AudioTrack implements android.media.AudioRouting {
     ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
-    method public void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
+    method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
+    method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public void flush();
     method public int getAudioFormat();
@@ -20798,7 +20896,8 @@
     method public void play() throws java.lang.IllegalStateException;
     method public void release();
     method public int reloadStaticData();
-    method public void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
+    method public deprecated void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
+    method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
     method public int setAuxEffectSendLevel(float);
     method public int setLoopPoints(int, int, int);
     method public int setNotificationMarkerPosition(int);
@@ -20851,8 +20950,8 @@
     method public abstract void onPeriodicNotification(android.media.AudioTrack);
   }
 
-  public static abstract interface AudioTrack.OnRoutingChangedListener {
-    method public abstract void onRoutingChanged(android.media.AudioTrack);
+  public static abstract deprecated interface AudioTrack.OnRoutingChangedListener {
+    method public abstract deprecated void onRoutingChanged(android.media.AudioTrack);
   }
 
   public class CamcorderProfile {
@@ -21670,6 +21769,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";
@@ -22004,6 +22104,7 @@
     field public static final int MIC = 1; // 0x1
     field public static final int RADIO_TUNER = 1998; // 0x7ce
     field public static final int REMOTE_SUBMIX = 8; // 0x8
+    field public static final int UNPROCESSED = 9; // 0x9
     field public static final int VOICE_CALL = 4; // 0x4
     field public static final int VOICE_COMMUNICATION = 7; // 0x7
     field public static final int VOICE_DOWNLINK = 3; // 0x3
@@ -24014,6 +24115,7 @@
     field public static final int FORMAT_AUDIBLE = 47364; // 0xb904
     field public static final int FORMAT_AVI = 12298; // 0x300a
     field public static final int FORMAT_BMP = 14340; // 0x3804
+    field public static final int FORMAT_DNG = 14353; // 0x3811
     field public static final int FORMAT_DPOF = 12294; // 0x3006
     field public static final int FORMAT_EXECUTABLE = 12291; // 0x3003
     field public static final int FORMAT_EXIF_JPEG = 14337; // 0x3801
@@ -24104,7 +24206,7 @@
     method public int[] getObjectHandles(int, int, int);
     method public android.mtp.MtpObjectInfo getObjectInfo(int);
     method public long getParent(int);
-    method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+    method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
     method public long getStorageId(int);
     method public int[] getStorageIds();
     method public android.mtp.MtpStorageInfo getStorageInfo(int);
@@ -25513,6 +25615,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;
@@ -25644,6 +25747,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();
@@ -25655,6 +25760,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();
@@ -25665,6 +25771,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();
@@ -26232,6 +26340,7 @@
 
   public final class Tag implements android.os.Parcelable {
     method public int describeContents();
+    method public boolean done(int);
     method public byte[] getId();
     method public java.lang.String[] getTechList();
     method public void writeToParcel(android.os.Parcel, int);
@@ -30476,7 +30585,12 @@
   }
 
   public class UserManager {
+    method public void clearSeedAccountData();
+    method public static android.content.Intent createUserCreationIntent(java.lang.String, java.lang.String, java.lang.String, android.os.PersistableBundle);
     method public android.os.Bundle getApplicationRestrictions(java.lang.String);
+    method public java.lang.String getSeedAccountName();
+    method public android.os.PersistableBundle getSeedAccountOptions();
+    method public java.lang.String getSeedAccountType();
     method public long getSerialNumberForUser(android.os.UserHandle);
     method public int getUserCount();
     method public long getUserCreationTime(android.os.UserHandle);
@@ -31386,6 +31500,22 @@
     field public static final java.lang.String _ID = "_id";
   }
 
+  public class BlockedNumberContract {
+    method public static boolean isBlocked(android.content.Context, java.lang.String);
+    field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
+    field public static final android.net.Uri AUTHORITY_URI;
+  }
+
+  public static class BlockedNumberContract.BlockedNumbers {
+    field public static final java.lang.String COLUMN_E164_NUMBER = "e164_number";
+    field public static final java.lang.String COLUMN_ID = "_id";
+    field public static final java.lang.String COLUMN_ORIGINAL_NUMBER = "original_number";
+    field public static final java.lang.String COLUMN_STRIPPED_NUMBER = "stripped_number";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
   public class Browser {
     ctor public Browser();
     method public static final void sendString(android.content.Context, java.lang.String);
@@ -35640,6 +35770,7 @@
     method public boolean onMenuOpened(int, android.view.Menu);
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -35734,6 +35865,7 @@
     method public abstract void onUnsubscribe(android.net.Uri);
     field public static final java.lang.String EXTRA_RULE_ID = "android.content.automatic.ruleId";
     field public static final java.lang.String META_DATA_CONFIGURATION_ACTIVITY = "android.service.zen.automatic.configurationActivity";
+    field public static final java.lang.String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit";
     field public static final java.lang.String META_DATA_RULE_TYPE = "android.service.zen.automatic.ruleType";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
   }
@@ -35893,17 +36025,24 @@
     method public java.lang.CharSequence getContentDescription();
     method public android.graphics.drawable.Icon getIcon();
     method public java.lang.CharSequence getLabel();
+    method public int getState();
     method public void setContentDescription(java.lang.CharSequence);
     method public void setIcon(android.graphics.drawable.Icon);
     method public void setLabel(java.lang.CharSequence);
+    method public void setState(int);
     method public void updateTile();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.quicksettings.Tile> CREATOR;
+    field public static final int STATE_ACTIVE = 2; // 0x2
+    field public static final int STATE_INACTIVE = 1; // 0x1
+    field public static final int STATE_UNAVAILABLE = 0; // 0x0
   }
 
   public class TileService extends android.app.Service {
     ctor public TileService();
     method public final android.service.quicksettings.Tile getQsTile();
+    method public final boolean isLocked();
+    method public final boolean isSecure();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onClick();
     method public void onStartListening();
@@ -35913,6 +36052,8 @@
     method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
     method public final void setStatusIcon(android.graphics.drawable.Icon, java.lang.String);
     method public final void showDialog(android.app.Dialog);
+    method public final void startActivityAndCollapse(android.content.Intent);
+    method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
     field public static final int TILE_MODE_ACTIVE = 2; // 0x2
     field public static final int TILE_MODE_PASSIVE = 1; // 0x1
@@ -37523,6 +37664,35 @@
     method public abstract void onVideoQualityChanged(int);
   }
 
+  public class ParcelableCallAnalytics implements android.os.Parcelable {
+    ctor public ParcelableCallAnalytics(long, long, int, boolean, boolean, int, int, boolean, java.lang.String, boolean);
+    ctor public ParcelableCallAnalytics(android.os.Parcel);
+    method public int describeContents();
+    method public long getCallDurationMillis();
+    method public int getCallTechnologies();
+    method public int getCallTerminationCode();
+    method public int getCallType();
+    method public java.lang.String getConnectionService();
+    method public long getStartTimeMillis();
+    method public boolean isAdditionalCall();
+    method public boolean isCreatedFromExistingConnection();
+    method public boolean isEmergencyCall();
+    method public boolean isInterrupted();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALLTYPE_INCOMING = 1; // 0x1
+    field public static final int CALLTYPE_OUTGOING = 2; // 0x2
+    field public static final int CALLTYPE_UNKNOWN = 0; // 0x0
+    field public static final int CDMA_PHONE = 1; // 0x1
+    field public static final android.os.Parcelable.Creator<android.telecom.ParcelableCallAnalytics> CREATOR;
+    field public static final int GSM_PHONE = 2; // 0x2
+    field public static final int IMS_PHONE = 4; // 0x4
+    field public static final long MILLIS_IN_1_SECOND = 1000L; // 0x3e8L
+    field public static final long MILLIS_IN_5_MINUTES = 300000L; // 0x493e0L
+    field public static final int SIP_PHONE = 8; // 0x8
+    field public static final int STILL_CONNECTED = -1; // 0xffffffff
+    field public static final int THIRD_PARTY_PHONE = 16; // 0x10
+  }
+
   public final deprecated class Phone {
     method public final void addListener(android.telecom.Phone.Listener);
     method public final boolean canAddCall();
@@ -37740,6 +37910,7 @@
     method public void cancelMissedCallsNotification();
     method public deprecated void clearAccounts();
     method public void clearPhoneAccounts();
+    method public java.util.List<android.telecom.ParcelableCallAnalytics> dumpAnalytics();
     method public void enablePhoneAccount(android.telecom.PhoneAccountHandle, boolean);
     method public boolean endCall();
     method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
@@ -37856,11 +38027,21 @@
     field public static final java.lang.String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS = "bool_allow_emergency_video_calls";
     field public static final java.lang.String BOOL_ALLOW_VIDEO_PAUSE = "bool_allow_video_pause";
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
+    field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final java.lang.String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool";
     field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool";
+    field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool";
+    field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool";
     field public static final java.lang.String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
     field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
     field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
+    field public static final java.lang.String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool";
+    field public static final java.lang.String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL = "carrier_ims_gba_required_bool";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL = "carrier_instant_lettering_available_bool";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING = "carrier_instant_lettering_encoding_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING = "carrier_instant_lettering_escaped_chars_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING = "carrier_instant_lettering_invalid_chars_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_LENGTH_LIMIT_INT = "carrier_instant_lettering_length_limit_int";
     field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
     field public static final java.lang.String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
@@ -37869,20 +38050,30 @@
     field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
     field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
     field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
+    field public static final java.lang.String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
     field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_BOOL = "ci_action_on_sys_update_bool";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING = "ci_action_on_sys_update_extra_string";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING = "ci_action_on_sys_update_intent_string";
     field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
     field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
     field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
     field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
+    field public static final java.lang.String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
     field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
+    field public static final java.lang.String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
     field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
+    field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
     field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
     field public static final java.lang.String KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL = "ignore_sim_network_locked_events_bool";
+    field public static final java.lang.String KEY_IMS_DTMF_TONE_DELAY_INT = "ims_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
     field public static final java.lang.String KEY_MMS_ALIAS_MAX_CHARS_INT = "aliasMaxChars";
     field public static final java.lang.String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars";
@@ -37916,10 +38107,12 @@
     field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
     field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
     field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
+    field public static final java.lang.String KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
     field public static final java.lang.String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
     field public static final java.lang.String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
     field public static final java.lang.String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool";
     field public static final java.lang.String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
+    field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
     field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
     field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
     field public static final java.lang.String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool";
@@ -38437,6 +38630,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();
@@ -38472,7 +38666,6 @@
     method public boolean isOffhook();
     method public boolean isRadioOn();
     method public boolean isRinging();
-    method public boolean isSimPinEnabled();
     method public boolean isSmsCapable();
     method public boolean isTtyModeSupported();
     method public boolean isVideoCallingEnabled();
@@ -40449,9 +40642,11 @@
 
   public class LocaleSpan extends android.text.style.MetricAffectingSpan implements android.text.ParcelableSpan {
     ctor public LocaleSpan(java.util.Locale);
+    ctor public LocaleSpan(android.util.LocaleList);
     ctor public LocaleSpan(android.os.Parcel);
     method public int describeContents();
     method public java.util.Locale getLocale();
+    method public android.util.LocaleList getLocales();
     method public int getSpanTypeId();
     method public void updateDrawState(android.text.TextPaint);
     method public void updateMeasureState(android.text.TextPaint);
@@ -40557,7 +40752,8 @@
     ctor public SuggestionSpan(android.os.Parcel);
     method public int describeContents();
     method public int getFlags();
-    method public java.lang.String getLocale();
+    method public deprecated java.lang.String getLocale();
+    method public java.util.Locale getLocaleObject();
     method public int getSpanTypeId();
     method public java.lang.String[] getSuggestions();
     method public void setFlags(int);
@@ -42741,6 +42937,27 @@
     method public void startTracking(android.view.KeyEvent, java.lang.Object);
   }
 
+  public final class KeyboardShortcutGroup implements android.os.Parcelable {
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>);
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence);
+    method public void addItem(android.view.KeyboardShortcutInfo);
+    method public int describeContents();
+    method public java.util.List<android.view.KeyboardShortcutInfo> getItems();
+    method public java.lang.CharSequence getLabel();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutGroup> CREATOR;
+  }
+
+  public final class KeyboardShortcutInfo implements android.os.Parcelable {
+    ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
+    method public int describeContents();
+    method public char getBaseCharacter();
+    method public java.lang.CharSequence getLabel();
+    method public int getModifiers();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutInfo> CREATOR;
+  }
+
   public abstract class LayoutInflater {
     ctor protected LayoutInflater(android.content.Context);
     ctor protected LayoutInflater(android.view.LayoutInflater, android.content.Context);
@@ -44743,6 +44960,7 @@
     method public abstract boolean onMenuOpened(int, android.view.Menu);
     method public abstract void onPanelClosed(int, android.view.Menu);
     method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public abstract void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public abstract boolean onSearchRequested();
     method public abstract boolean onSearchRequested(android.view.SearchEvent);
     method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -45070,6 +45288,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();
@@ -45132,6 +45351,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);
@@ -45688,6 +45908,7 @@
     method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public boolean commitText(java.lang.CharSequence, int);
     method public boolean deleteSurroundingText(int, int);
+    method public boolean deleteSurroundingTextInCodePoints(int, int);
     method public boolean endBatchEdit();
     method public boolean finishComposingText();
     method public static int getComposingSpanEnd(android.text.Spannable);
@@ -45853,6 +46074,7 @@
     method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public abstract boolean commitText(java.lang.CharSequence, int);
     method public abstract boolean deleteSurroundingText(int, int);
+    method public abstract boolean deleteSurroundingTextInCodePoints(int, int);
     method public abstract boolean endBatchEdit();
     method public abstract boolean finishComposingText();
     method public abstract int getCursorCapsMode(int);
@@ -45883,6 +46105,7 @@
     method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public boolean commitText(java.lang.CharSequence, int);
     method public boolean deleteSurroundingText(int, int);
+    method public boolean deleteSurroundingTextInCodePoints(int, int);
     method public boolean endBatchEdit();
     method public boolean finishComposingText();
     method public int getCursorCapsMode(int);
@@ -45945,6 +46168,7 @@
   }
 
   public final class InputMethodManager {
+    method public void dispatchKeyEventFromInputMethod(android.view.View, android.view.KeyEvent);
     method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]);
     method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype();
     method public java.util.List<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList();
@@ -46336,6 +46560,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);
@@ -46958,6 +47194,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);
@@ -48228,6 +48465,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 21b101f..111145b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -524,6 +524,7 @@
     field public static final int expandableListViewStyle = 16842863; // 0x101006f
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
+    field public static final int externalService = 16844047; // 0x101050f
     field public static final int extraTension = 16843371; // 0x101026b
     field public static final int extractNativeLibs = 16844010; // 0x10104ea
     field public static final int factor = 16843219; // 0x10101d3
@@ -2611,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();
@@ -2750,15 +2752,12 @@
     method public android.os.Bundle addAccountFromCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public abstract android.os.Bundle confirmCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public abstract android.os.Bundle editProperties(android.accounts.AccountAuthenticatorResponse, java.lang.String);
-    method public android.os.Bundle finishSession(android.accounts.AccountAuthenticatorResponse, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public android.os.Bundle getAccountCredentialsForCloning(android.accounts.AccountAuthenticatorResponse, android.accounts.Account) throws android.accounts.NetworkErrorException;
     method public android.os.Bundle getAccountRemovalAllowed(android.accounts.AccountAuthenticatorResponse, android.accounts.Account) throws android.accounts.NetworkErrorException;
     method public abstract android.os.Bundle getAuthToken(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
     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 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;
     field public static final java.lang.String KEY_CUSTOM_TOKEN_EXPIRY = "android.accounts.expiry";
   }
@@ -2796,7 +2795,6 @@
     method public void clearPassword(android.accounts.Account);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> confirmCredentials(android.accounts.Account, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
-    method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public static android.accounts.AccountManager get(android.content.Context);
     method public android.accounts.Account[] getAccounts();
     method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -2824,8 +2822,6 @@
     method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
     method public void setPassword(android.accounts.Account, java.lang.String);
     method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
-    method public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
-    method public android.accounts.AccountManagerFuture<android.os.Bundle> startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator";
     field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
@@ -2842,8 +2838,6 @@
     field public static final java.lang.String KEY_ACCOUNT_AUTHENTICATOR_RESPONSE = "accountAuthenticatorResponse";
     field public static final java.lang.String KEY_ACCOUNT_MANAGER_RESPONSE = "accountManagerResponse";
     field public static final java.lang.String KEY_ACCOUNT_NAME = "authAccount";
-    field public static final java.lang.String KEY_ACCOUNT_SESSION_BUNDLE = "accountSessionBundle";
-    field public static final java.lang.String KEY_ACCOUNT_STATUS_TOKEN = "accountStatusToken";
     field public static final java.lang.String KEY_ACCOUNT_TYPE = "accountType";
     field public static final java.lang.String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
     field public static final java.lang.String KEY_AUTHENTICATOR_TYPES = "authenticator_types";
@@ -3505,6 +3499,7 @@
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
     method public void onProvideAssistContent(android.app.assist.AssistContent);
     method public void onProvideAssistData(android.os.Bundle);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public android.net.Uri onProvideReferrer();
     method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
     method protected void onRestart();
@@ -4189,6 +4184,7 @@
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPrepareOptionsMenu(android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public void onRestoreInstanceState(android.os.Bundle);
     method public android.os.Bundle onSaveInstanceState();
     method public boolean onSearchRequested(android.view.SearchEvent);
@@ -5744,6 +5740,9 @@
     ctor public DeviceAdminReceiver();
     method public android.app.admin.DevicePolicyManager getManager(android.content.Context);
     method public android.content.ComponentName getWho(android.content.Context);
+    method public void onBugreportFailed(android.content.Context, android.content.Intent, int);
+    method public void onBugreportShared(android.content.Context, android.content.Intent, java.lang.String);
+    method public void onBugreportSharingDeclined(android.content.Context, android.content.Intent);
     method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, android.net.Uri, java.lang.String);
     method public java.lang.CharSequence onDisableRequested(android.content.Context, android.content.Intent);
     method public void onDisabled(android.content.Context, android.content.Intent);
@@ -5768,11 +5767,16 @@
     field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
     field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
     field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE";
+    field public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0; // 0x0
+    field public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1; // 0x1
     field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
     field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
     field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
   }
 
+  public static abstract class DeviceAdminReceiver.BugreportFailureCode implements java.lang.annotation.Annotation {
+  }
+
   public class DevicePolicyManager {
     method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5788,6 +5792,7 @@
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
     method public java.lang.String[] getAccountTypesWithManagementDisabled();
     method public java.util.List<android.content.ComponentName> getActiveAdmins();
+    method public java.lang.String getAlwaysOnVpnPackage(android.content.ComponentName);
     method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
     method public java.lang.String getApplicationRestrictionsManagingPackage(android.content.ComponentName);
     method public boolean getAutoTimeRequired();
@@ -5850,8 +5855,10 @@
     method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public boolean removeKeyPair(android.content.ComponentName, java.lang.String);
     method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
+    method public boolean requestBugreport(android.content.ComponentName);
     method public boolean resetPassword(java.lang.String, int);
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
+    method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String);
     method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
     method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void setApplicationRestrictionsManagingPackage(android.content.ComponentName, java.lang.String);
@@ -5907,6 +5914,7 @@
     field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_DEVICE = "android.app.action.PROVISION_MANAGED_DEVICE";
     field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
+    field public static final java.lang.String ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = "android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD";
     field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
     field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
     field public static final java.lang.String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
@@ -6472,6 +6480,30 @@
 
 }
 
+package android.auditing {
+
+  public class SecurityLog {
+    ctor public SecurityLog();
+    field public static final int TAG_ADB_SHELL_CMD = 210002; // 0x33452
+    field public static final int TAG_ADB_SHELL_INTERACTIVE = 210001; // 0x33451
+    field public static final int TAG_APP_PROCESS_START = 210005; // 0x33455
+    field public static final int TAG_DEVICE_LOCKED = 210007; // 0x33457
+    field public static final int TAG_DEVICE_UNLOCK_ATTEMPT = 210006; // 0x33456
+    field public static final int TAG_SYNC_RECV_FILE = 210003; // 0x33453
+    field public static final int TAG_SYNC_SEND_FILE = 210004; // 0x33454
+  }
+
+  public static class SecurityLog.SecurityEvent implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.Object getData();
+    method public int getTag();
+    method public long getTimeNanos();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.auditing.SecurityLog.SecurityEvent> CREATOR;
+  }
+
+}
+
 package android.bluetooth {
 
   public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
@@ -7205,6 +7237,15 @@
     field public static final int TYPE_SCO = 2; // 0x2
   }
 
+  public class OobData implements android.os.Parcelable {
+    ctor public OobData();
+    method public int describeContents();
+    method public byte[] getSecurityManagerTk();
+    method public void setSecurityManagerTk(byte[]);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR;
+  }
+
 }
 
 package android.bluetooth.le {
@@ -8391,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";
@@ -9299,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);
@@ -9315,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 {
@@ -19366,6 +19412,7 @@
     field public static final deprecated int NUM_STREAMS = 5; // 0x5
     field public static final java.lang.String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
     field public static final java.lang.String PROPERTY_OUTPUT_SAMPLE_RATE = "android.media.property.OUTPUT_SAMPLE_RATE";
+    field public static final java.lang.String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED = "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
     field public static final java.lang.String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
     field public static final java.lang.String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
     field public static final java.lang.String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
@@ -19403,9 +19450,10 @@
     method public abstract void onAudioFocusChange(int);
   }
 
-  public class AudioRecord {
+  public class AudioRecord implements android.media.AudioRouting {
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
-    method public void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method public deprecated void addOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener, android.os.Handler);
+    method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -19429,7 +19477,8 @@
     method public int read(java.nio.ByteBuffer, int);
     method public int read(java.nio.ByteBuffer, int, int);
     method public void release();
-    method public void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
+    method public deprecated void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
+    method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
     method public int setNotificationMarkerPosition(int);
     method public int setPositionNotificationPeriod(int);
     method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
@@ -19467,17 +19516,29 @@
     method public abstract void onRoutingChanged(android.media.AudioRecord);
   }
 
+  public abstract interface AudioRouting {
+    method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
+    method public abstract android.media.AudioDeviceInfo getPreferredDevice();
+    method public abstract void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
+    method public abstract boolean setPreferredDevice(android.media.AudioDeviceInfo);
+  }
+
+  public static abstract interface AudioRouting.OnRoutingChangedListener {
+    method public abstract void onRoutingChanged(android.media.AudioRouting);
+  }
+
   public final class AudioTimestamp {
     ctor public AudioTimestamp();
     field public long framePosition;
     field public long nanoTime;
   }
 
-  public class AudioTrack {
+  public class AudioTrack implements android.media.AudioRouting {
     ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
-    method public void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
+    method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
+    method public void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public void flush();
     method public int getAudioFormat();
@@ -19507,7 +19568,8 @@
     method public void play() throws java.lang.IllegalStateException;
     method public void release();
     method public int reloadStaticData();
-    method public void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
+    method public deprecated void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
+    method public void removeOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener);
     method public int setAuxEffectSendLevel(float);
     method public int setLoopPoints(int, int, int);
     method public int setNotificationMarkerPosition(int);
@@ -19560,8 +19622,8 @@
     method public abstract void onPeriodicNotification(android.media.AudioTrack);
   }
 
-  public static abstract interface AudioTrack.OnRoutingChangedListener {
-    method public abstract void onRoutingChanged(android.media.AudioTrack);
+  public static abstract deprecated interface AudioTrack.OnRoutingChangedListener {
+    method public abstract deprecated void onRoutingChanged(android.media.AudioTrack);
   }
 
   public class CamcorderProfile {
@@ -20379,6 +20441,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";
@@ -20711,6 +20774,7 @@
     field public static final int DEFAULT = 0; // 0x0
     field public static final int MIC = 1; // 0x1
     field public static final int REMOTE_SUBMIX = 8; // 0x8
+    field public static final int UNPROCESSED = 9; // 0x9
     field public static final int VOICE_CALL = 4; // 0x4
     field public static final int VOICE_COMMUNICATION = 7; // 0x7
     field public static final int VOICE_DOWNLINK = 3; // 0x3
@@ -22475,6 +22539,7 @@
     field public static final int FORMAT_AUDIBLE = 47364; // 0xb904
     field public static final int FORMAT_AVI = 12298; // 0x300a
     field public static final int FORMAT_BMP = 14340; // 0x3804
+    field public static final int FORMAT_DNG = 14353; // 0x3811
     field public static final int FORMAT_DPOF = 12294; // 0x3006
     field public static final int FORMAT_EXECUTABLE = 12291; // 0x3003
     field public static final int FORMAT_EXIF_JPEG = 14337; // 0x3801
@@ -22565,7 +22630,7 @@
     method public int[] getObjectHandles(int, int, int);
     method public android.mtp.MtpObjectInfo getObjectInfo(int);
     method public long getParent(int);
-    method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+    method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
     method public long getStorageId(int);
     method public int[] getStorageIds();
     method public android.mtp.MtpStorageInfo getStorageInfo(int);
@@ -24248,6 +24313,7 @@
 
   public final class Tag implements android.os.Parcelable {
     method public int describeContents();
+    method public boolean done(int);
     method public byte[] getId();
     method public java.lang.String[] getTechList();
     method public void writeToParcel(android.os.Parcel, int);
@@ -28481,6 +28547,7 @@
   }
 
   public class UserManager {
+    method public static android.content.Intent createUserCreationIntent(java.lang.String, java.lang.String, java.lang.String, android.os.PersistableBundle);
     method public android.os.Bundle getApplicationRestrictions(java.lang.String);
     method public long getSerialNumberForUser(android.os.UserHandle);
     method public int getUserCount();
@@ -29393,6 +29460,22 @@
     field public static final java.lang.String _ID = "_id";
   }
 
+  public class BlockedNumberContract {
+    method public static boolean isBlocked(android.content.Context, java.lang.String);
+    field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
+    field public static final android.net.Uri AUTHORITY_URI;
+  }
+
+  public static class BlockedNumberContract.BlockedNumbers {
+    field public static final java.lang.String COLUMN_E164_NUMBER = "e164_number";
+    field public static final java.lang.String COLUMN_ID = "_id";
+    field public static final java.lang.String COLUMN_ORIGINAL_NUMBER = "original_number";
+    field public static final java.lang.String COLUMN_STRIPPED_NUMBER = "stripped_number";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
   public class Browser {
     ctor public Browser();
     method public static final void sendString(android.content.Context, java.lang.String);
@@ -33516,6 +33599,7 @@
     method public boolean onMenuOpened(int, android.view.Menu);
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -33610,6 +33694,7 @@
     method public abstract void onUnsubscribe(android.net.Uri);
     field public static final java.lang.String EXTRA_RULE_ID = "android.content.automatic.ruleId";
     field public static final java.lang.String META_DATA_CONFIGURATION_ACTIVITY = "android.service.zen.automatic.configurationActivity";
+    field public static final java.lang.String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit";
     field public static final java.lang.String META_DATA_RULE_TYPE = "android.service.zen.automatic.ruleType";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
   }
@@ -33737,17 +33822,24 @@
     method public java.lang.CharSequence getContentDescription();
     method public android.graphics.drawable.Icon getIcon();
     method public java.lang.CharSequence getLabel();
+    method public int getState();
     method public void setContentDescription(java.lang.CharSequence);
     method public void setIcon(android.graphics.drawable.Icon);
     method public void setLabel(java.lang.CharSequence);
+    method public void setState(int);
     method public void updateTile();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.quicksettings.Tile> CREATOR;
+    field public static final int STATE_ACTIVE = 2; // 0x2
+    field public static final int STATE_INACTIVE = 1; // 0x1
+    field public static final int STATE_UNAVAILABLE = 0; // 0x0
   }
 
   public class TileService extends android.app.Service {
     ctor public TileService();
     method public final android.service.quicksettings.Tile getQsTile();
+    method public final boolean isLocked();
+    method public final boolean isSecure();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onClick();
     method public void onStartListening();
@@ -33756,6 +33848,8 @@
     method public void onTileRemoved();
     method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
     method public final void showDialog(android.app.Dialog);
+    method public final void startActivityAndCollapse(android.content.Intent);
+    method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
     field public static final int TILE_MODE_ACTIVE = 2; // 0x2
     field public static final int TILE_MODE_PASSIVE = 1; // 0x1
@@ -35584,12 +35678,24 @@
     method public android.os.PersistableBundle getConfigForSubId(int);
     method public void notifyConfigChangedForSubId(int);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+    field public static final java.lang.String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS = "bool_allow_emergency_video_calls";
+    field public static final java.lang.String BOOL_ALLOW_VIDEO_PAUSE = "bool_allow_video_pause";
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
+    field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final java.lang.String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool";
     field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool";
+    field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool";
+    field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool";
     field public static final java.lang.String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
     field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
     field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
+    field public static final java.lang.String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool";
+    field public static final java.lang.String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL = "carrier_ims_gba_required_bool";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL = "carrier_instant_lettering_available_bool";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING = "carrier_instant_lettering_encoding_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING = "carrier_instant_lettering_escaped_chars_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING = "carrier_instant_lettering_invalid_chars_string";
+    field public static final java.lang.String KEY_CARRIER_INSTANT_LETTERING_LENGTH_LIMIT_INT = "carrier_instant_lettering_length_limit_int";
     field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
     field public static final java.lang.String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
@@ -35598,20 +35704,30 @@
     field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
     field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
     field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
+    field public static final java.lang.String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
     field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_BOOL = "ci_action_on_sys_update_bool";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING = "ci_action_on_sys_update_extra_string";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING = "ci_action_on_sys_update_extra_val_string";
+    field public static final java.lang.String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING = "ci_action_on_sys_update_intent_string";
     field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
     field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
     field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
     field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool";
+    field public static final java.lang.String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
     field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
+    field public static final java.lang.String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array";
     field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
+    field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
     field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
     field public static final java.lang.String KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL = "ignore_sim_network_locked_events_bool";
+    field public static final java.lang.String KEY_IMS_DTMF_TONE_DELAY_INT = "ims_dtmf_tone_delay_int";
     field public static final java.lang.String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
     field public static final java.lang.String KEY_MMS_ALIAS_MAX_CHARS_INT = "aliasMaxChars";
     field public static final java.lang.String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars";
@@ -35645,14 +35761,17 @@
     field public static final java.lang.String KEY_MMS_USER_AGENT_STRING = "userAgent";
     field public static final java.lang.String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
     field public static final java.lang.String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
+    field public static final java.lang.String KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
     field public static final java.lang.String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
     field public static final java.lang.String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
     field public static final java.lang.String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool";
     field public static final java.lang.String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
+    field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
     field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
     field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
     field public static final java.lang.String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool";
     field public static final java.lang.String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
+    field public static final java.lang.String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool";
     field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
     field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
     field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
@@ -36146,6 +36265,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();
@@ -38114,9 +38234,11 @@
 
   public class LocaleSpan extends android.text.style.MetricAffectingSpan implements android.text.ParcelableSpan {
     ctor public LocaleSpan(java.util.Locale);
+    ctor public LocaleSpan(android.util.LocaleList);
     ctor public LocaleSpan(android.os.Parcel);
     method public int describeContents();
     method public java.util.Locale getLocale();
+    method public android.util.LocaleList getLocales();
     method public int getSpanTypeId();
     method public void updateDrawState(android.text.TextPaint);
     method public void updateMeasureState(android.text.TextPaint);
@@ -38222,7 +38344,8 @@
     ctor public SuggestionSpan(android.os.Parcel);
     method public int describeContents();
     method public int getFlags();
-    method public java.lang.String getLocale();
+    method public deprecated java.lang.String getLocale();
+    method public java.util.Locale getLocaleObject();
     method public int getSpanTypeId();
     method public java.lang.String[] getSuggestions();
     method public void setFlags(int);
@@ -40406,6 +40529,27 @@
     method public void startTracking(android.view.KeyEvent, java.lang.Object);
   }
 
+  public final class KeyboardShortcutGroup implements android.os.Parcelable {
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>);
+    ctor public KeyboardShortcutGroup(java.lang.CharSequence);
+    method public void addItem(android.view.KeyboardShortcutInfo);
+    method public int describeContents();
+    method public java.util.List<android.view.KeyboardShortcutInfo> getItems();
+    method public java.lang.CharSequence getLabel();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutGroup> CREATOR;
+  }
+
+  public final class KeyboardShortcutInfo implements android.os.Parcelable {
+    ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
+    method public int describeContents();
+    method public char getBaseCharacter();
+    method public java.lang.CharSequence getLabel();
+    method public int getModifiers();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.KeyboardShortcutInfo> CREATOR;
+  }
+
   public abstract class LayoutInflater {
     ctor protected LayoutInflater(android.content.Context);
     ctor protected LayoutInflater(android.view.LayoutInflater, android.content.Context);
@@ -42407,6 +42551,7 @@
     method public abstract boolean onMenuOpened(int, android.view.Menu);
     method public abstract void onPanelClosed(int, android.view.Menu);
     method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
+    method public abstract void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public abstract boolean onSearchRequested();
     method public abstract boolean onSearchRequested(android.view.SearchEvent);
     method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -42732,6 +42877,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();
@@ -42794,6 +42940,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);
@@ -43350,6 +43497,7 @@
     method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public boolean commitText(java.lang.CharSequence, int);
     method public boolean deleteSurroundingText(int, int);
+    method public boolean deleteSurroundingTextInCodePoints(int, int);
     method public boolean endBatchEdit();
     method public boolean finishComposingText();
     method public static int getComposingSpanEnd(android.text.Spannable);
@@ -43515,6 +43663,7 @@
     method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public abstract boolean commitText(java.lang.CharSequence, int);
     method public abstract boolean deleteSurroundingText(int, int);
+    method public abstract boolean deleteSurroundingTextInCodePoints(int, int);
     method public abstract boolean endBatchEdit();
     method public abstract boolean finishComposingText();
     method public abstract int getCursorCapsMode(int);
@@ -43545,6 +43694,7 @@
     method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
     method public boolean commitText(java.lang.CharSequence, int);
     method public boolean deleteSurroundingText(int, int);
+    method public boolean deleteSurroundingTextInCodePoints(int, int);
     method public boolean endBatchEdit();
     method public boolean finishComposingText();
     method public int getCursorCapsMode(int);
@@ -43607,6 +43757,7 @@
   }
 
   public final class InputMethodManager {
+    method public void dispatchKeyEventFromInputMethod(android.view.View, android.view.KeyEvent);
     method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]);
     method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype();
     method public java.util.List<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList();
@@ -45577,6 +45728,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/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index b7c729b..63f6c92 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -19,11 +19,13 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.net.Uri;
+import android.os.IUserManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
-import android.text.TextUtils;
 
 import com.android.internal.os.BaseCommand;
 import com.android.internal.telecom.ITelecomService;
@@ -53,16 +55,17 @@
     private ComponentName mComponent;
     private String mAccountId;
     private ITelecomService mTelecomService;
+    private IUserManager mUserManager;
 
     @Override
     public void onShowUsage(PrintStream out) {
         out.println(
                 "usage: telecom [subcommand] [options]\n" +
-                "usage: telecom set-phone-account-enabled <COMPONENT> <ID>\n" +
-                "usage: telecom set-phone-account-disabled <COMPONENT> <ID>\n" +
-                "usage: telecom register-phone-account <COMPONENT> <ID> <LABEL>\n" +
-                "usage: telecom register-sim-phone-account <COMPONENT> <ID> <LABEL> <ADDRESS>\n" +
-                "usage: telecom unregister-phone-account <COMPONENT> <ID>\n" +
+                "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n" +
+                "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n" +
+                "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n" +
+                "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN> <LABEL> <ADDRESS>\n" +
+                "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n" +
                 "usage: telecom set-default-dialer <PACKAGE>\n" +
                 "usage: telecom get-default-dialer\n" +
                 "usage: telecom get-system-dialer\n" +
@@ -89,6 +92,12 @@
             showError("Error: Could not access the Telecom Manager. Is the system running?");
             return;
         }
+        mUserManager = IUserManager.Stub
+                .asInterface(ServiceManager.getService(Context.USER_SERVICE));
+        if (mUserManager == null) {
+            showError("Error: Could not access the User Manager. Is the system running?");
+            return;
+        }
 
         String command = nextArgRequired();
         switch (command) {
@@ -183,10 +192,18 @@
         System.out.println(mTelecomService.getSystemDialerPackage());
     }
 
-    private PhoneAccountHandle getPhoneAccountHandleFromArgs() {
+    private PhoneAccountHandle getPhoneAccountHandleFromArgs() throws RemoteException{
         final ComponentName component = parseComponentName(nextArgRequired());
         final String accountId = nextArgRequired();
-        return new PhoneAccountHandle(component, accountId);
+        final String userSnInStr = nextArgRequired();
+        UserHandle userHandle;
+        try {
+            final int userSn = Integer.parseInt(userSnInStr);
+            userHandle = UserHandle.of(mUserManager.getUserHandle(userSn));
+        } catch (NumberFormatException ex) {
+            throw new IllegalArgumentException ("Invalid user serial number " + userSnInStr);
+        }
+        return new PhoneAccountHandle(component, accountId, userHandle);
     }
 
     private ComponentName parseComponentName(String component) {
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 a312e3f..4dca8e2 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -16,15 +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.Manifest;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
-import android.Manifest;
+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;
@@ -435,6 +436,7 @@
             }
         }
 
+        @Override
         public void finishSession(
                 IAccountAuthenticatorResponse response,
                 String accountType,
@@ -460,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,
@@ -762,7 +782,9 @@
      * @throws NetworkErrorException if the authenticator could not honor the
      *             request due to a network error
      * @see #finishSession(AccountAuthenticatorResponse, String, Bundle)
+     * @hide
      */
+    @SystemApi
     public Bundle startAddAccountSession(
             final AccountAuthenticatorResponse response,
             final String accountType,
@@ -818,7 +840,9 @@
      * @throws NetworkErrorException if the authenticator could not honor the
      *             request due to a network error
      * @see #finishSession(AccountAuthenticatorResponse, String, Bundle)
+     * @hide
      */
+    @SystemApi
     public Bundle startUpdateCredentialsSession(
             final AccountAuthenticatorResponse response,
             final Account account,
@@ -868,9 +892,12 @@
      *         <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
      */
+    @SystemApi
     public Bundle finishSession(
             final AccountAuthenticatorResponse response,
             final String accountType,
@@ -937,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 ada1ac2..259f0da 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -16,9 +16,12 @@
 
 package android.accounts;
 
+import static android.Manifest.permission.GET_ACCOUNTS;
+
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.Size;
+import android.annotation.SystemApi;
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -53,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
@@ -244,14 +245,18 @@
      * Bundle key used for a {@link Bundle} in result from
      * {@link #startAddAccountSession} and friends which returns session data
      * for installing an account later.
+     * @hide
      */
+    @SystemApi
     public static final String KEY_ACCOUNT_SESSION_BUNDLE = "accountSessionBundle";
 
     /**
      * Bundle key used for the {@link String} account status token in result
      * from {@link #startAddAccountSession} and friends which returns
      * information about a particular account.
+     * @hide
      */
+    @SystemApi
     public static final String KEY_ACCOUNT_STATUS_TOKEN = "accountStatusToken";
 
     public static final String ACTION_AUTHENTICATOR_INTENT =
@@ -1848,6 +1853,22 @@
         }.start();
     }
 
+    /**
+     * @hide
+     * Checks if the given account exists on any of the users on the device.
+     * Only the system process can call this method.
+     *
+     * @param account The account to check for existence.
+     * @return whether any user has this account
+     */
+    public boolean someUserHasAccount(@NonNull final Account account) {
+        try {
+            return mService.someUserHasAccount(account);
+        } catch (RemoteException re) {
+            throw new RuntimeException(re);
+        }
+    }
+
     private void ensureNotOnMainThread() {
         final Looper looper = Looper.myLooper();
         if (looper != null && looper == mContext.getMainLooper()) {
@@ -2667,7 +2688,9 @@
      *         trouble
      *         </ul>
      * @see #finishSession
+     * @hide
      */
+    @SystemApi
     public AccountManagerFuture<Bundle> startAddAccountSession(
             final String accountType,
             final String authTokenType,
@@ -2749,7 +2772,9 @@
      *         trouble
      *         </ul>
      * @see #finishSession
+     * @hide
      */
+    @SystemApi
     public AccountManagerFuture<Bundle> startUpdateCredentialsSession(
             final Account account,
             final String authTokenType,
@@ -2818,7 +2843,9 @@
      *         trouble
      *         </ul>
      * @see #startAddAccountSession and #startUpdateCredentialsSession
+     * @hide
      */
+    @SystemApi
     public AccountManagerFuture<Bundle> finishSession(
             final Bundle sessionBundle,
             final Activity activity,
@@ -2839,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 4af9f33..39dedf4 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -95,4 +95,11 @@
     /* Finish session started by startAddAccountSession(...) or startUpdateCredentialsSession(...) */
     void finishSession(in IAccountManagerResponse response, in Bundle sessionBundle,
         boolean expectActivityLaunch, in Bundle appInfo);
+
+    /* 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/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 7f9a5d3..e721de9 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -17,6 +17,7 @@
 package android.animation;
 
 import android.annotation.CallSuper;
+import android.annotation.IntDef;
 import android.os.Looper;
 import android.os.Trace;
 import android.util.AndroidRuntimeException;
@@ -25,6 +26,8 @@
 import android.view.animation.AnimationUtils;
 import android.view.animation.LinearInterpolator;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -234,6 +237,11 @@
      * Public constants
      */
 
+    /** @hide */
+    @IntDef({RESTART, REVERSE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RepeatMode {}
+
     /**
      * When the animation reaches the end and <code>repeatCount</code> is INFINITE
      * or a positive value, the animation restarts from the beginning.
@@ -807,7 +815,7 @@
      *
      * @param value {@link #RESTART} or {@link #REVERSE}
      */
-    public void setRepeatMode(int value) {
+    public void setRepeatMode(@RepeatMode int value) {
         mRepeatMode = value;
     }
 
@@ -816,6 +824,7 @@
      *
      * @return either one of {@link #REVERSE} or {@link #RESTART}
      */
+    @RepeatMode
     public int getRepeatMode() {
         return mRepeatMode;
     }
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
index a18bfa5..434a9c7 100644
--- a/core/java/android/annotation/IntDef.java
+++ b/core/java/android/annotation/IntDef.java
@@ -42,7 +42,7 @@
  * For a flag, set the flag attribute:
  * <pre><code>
  *  &#64;IntDef(
- *      flag = true
+ *      flag = true,
  *      value = {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
  * </code></pre>
  *
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 34527c2..e312596 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -62,6 +62,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.media.AudioManager;
 import android.media.session.MediaController;
 import android.net.Uri;
@@ -71,6 +72,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.StrictMode;
 import android.os.UserHandle;
@@ -78,23 +80,28 @@
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.method.TextKeyListener;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SuperNotCalledException;
 import android.view.ActionMode;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.ContextThemeWrapper;
 import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.KeyboardShortcutInfo;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
-import com.android.internal.policy.PhoneWindow;
 import android.view.SearchEvent;
 import android.view.View;
 import android.view.View.OnCreateContextMenuListener;
@@ -103,10 +110,17 @@
 import android.view.ViewManager;
 import android.view.ViewRootImpl;
 import android.view.Window;
+import android.view.Window.WindowControllerCallback;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
+import android.widget.Toolbar;
+
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.app.ToolbarActionBar;
+import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.policy.PhoneWindow;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -116,6 +130,8 @@
 import java.util.HashMap;
 import java.util.List;
 
+import static java.lang.Character.MIN_VALUE;
+
 /**
  * An activity is a single, focused thing that the user can do.  Almost all
  * activities interact with the user, so the Activity class takes care of
@@ -1594,6 +1610,30 @@
     public void onProvideAssistContent(AssistContent outContent) {
     }
 
+    @Override
+    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
+        if (menu == null) {
+          return;
+        }
+        KeyboardShortcutGroup group = null;
+        int menuSize = menu.size();
+        for (int i = 0; i < menuSize; ++i) {
+            final MenuItem item = menu.getItem(i);
+            final CharSequence title = item.getTitle();
+            final char alphaShortcut = item.getAlphabeticShortcut();
+            if (title != null && alphaShortcut != MIN_VALUE) {
+                if (group == null) {
+                    group = new KeyboardShortcutGroup(null /* no label */);
+                }
+                group.addItem(new KeyboardShortcutInfo(
+                    title, alphaShortcut, KeyEvent.META_CTRL_ON));
+            }
+        }
+        if (group != null) {
+            data.add(group);
+        }
+    }
+
     /**
      * Ask to have the current assistant shown to the user.  This only works if the calling
      * activity is the current foreground activity.  It is the same as calling
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/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 624131e..63b6825 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2798,7 +2798,8 @@
         case MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             final int stackId = data.readInt();
-            moveTasksToFullscreenStack(stackId);
+            final boolean onTop = data.readInt() == 1;
+            moveTasksToFullscreenStack(stackId, onTop);
             reply.writeNoException();
             return true;
         }
@@ -2842,6 +2843,14 @@
             reply.writeNoException();
             return true;
         }
+        case IS_APP_FOREGROUND_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final int userHandle = data.readInt();
+            final boolean isForeground = isAppForeground(userHandle);
+            reply.writeNoException();
+            reply.writeInt(isForeground ? 1 : 0);
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -6573,11 +6582,12 @@
     }
 
     @Override
-    public void moveTasksToFullscreenStack(int fromStackId) throws RemoteException {
+    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(fromStackId);
+        data.writeInt(onTop ? 1 : 0);
         mRemote.transact(MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -6639,5 +6649,18 @@
         reply.recycle();
     }
 
+    @Override
+    public boolean isAppForeground(int uid) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(uid);
+        mRemote.transact(IS_APP_FOREGROUND_TRANSACTION, data, reply, 0);
+        final boolean isForeground = reply.readInt() == 1 ? true : false;
+        data.recycle();
+        reply.recycle();
+        return isForeground;
+    };
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index e596a68..b42cf68 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1125,4 +1125,11 @@
         return null;
     }
 
+    /** @hide */
+    @Override
+    public String toString() {
+        return "ActivityOptions(" + hashCode() + "), mPackageName=" + mPackageName
+                + ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
+                + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
+    }
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4e55c89..93122dd 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4325,6 +4325,21 @@
 
         r.activity.mChangingConfigurations = true;
 
+        // If we are preserving the main window across relaunches we would also like to preserve
+        // the children. However the client side view system does not support preserving
+        // the child views so we notify the window manager to expect these windows to
+        // be replaced and defer requests to destroy or hide them. This way we can achieve
+        // visual continuity. It's important that we do this here prior to pause and destroy
+        // as that is when we may hide or remove the child views.
+        try {
+            if (r.mPreserveWindow) {
+                WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token);
+            }
+        } catch (RemoteException e) {
+            // If the system process has died, it's game over for everyone.
+        }
+
+
         // Need to ensure state is saved.
         if (!r.paused) {
             performPauseActivity(r.token, false, r.isPreHoneycomb());
@@ -4362,6 +4377,9 @@
         if (!tmp.onlyLocalRequest) {
             try {
                 ActivityManagerNative.getDefault().activityRelaunched(r.token);
+                if (r.window != null) {
+                    r.window.reportActivityRelaunched();
+                }
             } catch (RemoteException e) {
                 // If the system process has died, it's game over for everyone.
             }
@@ -4720,6 +4738,9 @@
     }
 
     private static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) {
+        if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
+            return;
+        }
         final ApplicationInfo appInfo = loadedApk.getApplicationInfo();
         if (isSharingRuntime(appInfo)) {
             // If sharing is enabled we do not have a unique application
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index e28fb20..af840d0 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -894,7 +894,9 @@
             final View decor = getDecor();
             if (decor != null) {
                 final ViewRootImpl viewRoot = decor.getViewRootImpl();
-                viewRoot.setPausedForTransition(false);
+                if (viewRoot != null) {
+                    viewRoot.setPausedForTransition(false);
+                }
             }
             onTransitionsComplete();
         }
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 8d7f347..bbf1607 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -23,7 +23,6 @@
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
-import android.text.format.DateUtils;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -49,19 +48,16 @@
     private static final String DAY = "day";
 
     private final DatePicker mDatePicker;
-    private final Calendar mCalendar;
 
     private OnDateSetListener mDateSetListener;
 
-    private boolean mTitleNeedsUpdate = true;
-
     /**
      * Creates a new date picker dialog for the current date using the parent
      * context's default date picker dialog theme.
      *
      * @param context the parent context
      */
-    public DatePickerDialog(Context context) {
+    public DatePickerDialog(@NonNull Context context) {
         this(context, 0);
     }
 
@@ -73,7 +69,7 @@
      *                   this dialog, or {@code 0} to use the parent
      *                   {@code context}'s default alert dialog theme
      */
-    public DatePickerDialog(Context context, @StyleRes int themeResId) {
+    public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId) {
         super(context, resolveDialogTheme(context, themeResId));
 
         final Context themeContext = getContext();
@@ -85,11 +81,10 @@
         setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this);
         setButtonPanelLayoutHint(LAYOUT_HINT_SIDE);
 
-        mCalendar = Calendar.getInstance();
-
-        final int year = mCalendar.get(Calendar.YEAR);
-        final int monthOfYear = mCalendar.get(Calendar.MONTH);
-        final int dayOfMonth = mCalendar.get(Calendar.DAY_OF_MONTH);
+        final Calendar calendar = Calendar.getInstance();
+        final int year = calendar.get(Calendar.YEAR);
+        final int monthOfYear = calendar.get(Calendar.MONTH);
+        final int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
         mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
         mDatePicker.init(year, monthOfYear, dayOfMonth, this);
         mDatePicker.setValidationCallback(mValidationCallback);
@@ -107,7 +102,7 @@
      * @param dayOfMonth the initially selected day of month (1-31, depending
      *                   on month)
      */
-    public DatePickerDialog(@Nullable Context context, @Nullable OnDateSetListener listener,
+    public DatePickerDialog(@NonNull Context context, @Nullable OnDateSetListener listener,
             int year, int month, int dayOfMonth) {
         this(context, 0, listener, year, month, dayOfMonth);
     }
@@ -135,7 +130,7 @@
         mDatePicker.updateDate(year, month, dayOfMonth);
     }
 
-    static int resolveDialogTheme(@NonNull Context context, @StyleRes int themeResId) {
+    static @StyleRes int resolveDialogTheme(@NonNull Context context, @StyleRes int themeResId) {
         if (themeResId == 0) {
             final TypedValue outValue = new TypedValue();
             context.getTheme().resolveAttribute(R.attr.datePickerDialogTheme, outValue, true);
@@ -146,9 +141,8 @@
     }
 
     @Override
-    public void onDateChanged(DatePicker view, int year, int month, int dayOfMonth) {
+    public void onDateChanged(@NonNull DatePicker view, int year, int month, int dayOfMonth) {
         mDatePicker.init(year, month, dayOfMonth, this);
-        updateTitle(year, month, dayOfMonth);
     }
 
     /**
@@ -161,7 +155,7 @@
     }
 
     @Override
-    public void onClick(DialogInterface dialog, int which) {
+    public void onClick(@NonNull DialogInterface dialog, int which) {
         switch (which) {
             case BUTTON_POSITIVE:
                 if (mDateSetListener != null) {
@@ -200,29 +194,6 @@
         mDatePicker.updateDate(year, month, dayOfMonth);
     }
 
-    private void updateTitle(int year, int month, int dayOfMonth) {
-        if (!mDatePicker.getCalendarViewShown()) {
-            mCalendar.set(Calendar.YEAR, year);
-            mCalendar.set(Calendar.MONTH, month);
-            mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
-
-            final String title = DateUtils.formatDateTime(mContext,
-                    mCalendar.getTimeInMillis(),
-                    DateUtils.FORMAT_SHOW_DATE
-                    | DateUtils.FORMAT_SHOW_WEEKDAY
-                    | DateUtils.FORMAT_SHOW_YEAR
-                    | DateUtils.FORMAT_ABBREV_MONTH
-                    | DateUtils.FORMAT_ABBREV_WEEKDAY);
-            setTitle(title);
-
-            mTitleNeedsUpdate = true;
-        } else if (mTitleNeedsUpdate) {
-            setTitle(R.string.date_picker_dialog_title);
-
-            mTitleNeedsUpdate = false;
-        }
-    }
-
     @Override
     public Bundle onSaveInstanceState() {
         final Bundle state = super.onSaveInstanceState();
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 6e8e2c4..79461b4 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -21,9 +21,8 @@
 import android.annotation.IdRes;
 import android.annotation.LayoutRes;
 import android.annotation.NonNull;
-import android.annotation.StringRes;
-
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.annotation.StyleRes;
 import android.content.ComponentName;
 import android.content.Context;
@@ -44,11 +43,11 @@
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
-import com.android.internal.policy.PhoneWindow;
 import android.view.SearchEvent;
 import android.view.View;
 import android.view.View.OnCreateContextMenuListener;
@@ -60,8 +59,10 @@
 
 import com.android.internal.R;
 import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.policy.PhoneWindow;
 
 import java.lang.ref.WeakReference;
+import java.util.List;
 
 /**
  * Base class for Dialogs.
@@ -1081,6 +1082,13 @@
     }
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
+    }
+
+    /**
      * @return The activity associated with this dialog, or null if there is no associated activity.
      */
     private ComponentName getAssociatedActivity() {
diff --git a/core/java/android/app/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/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 1ae91a6..5bb2cf5 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -577,7 +577,7 @@
 
     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException;
 
-    public void moveTasksToFullscreenStack(int fromStackId) throws RemoteException;
+    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) throws RemoteException;
 
     public int getAppStartMode(int uid, String packageName) throws RemoteException;
 
@@ -589,6 +589,8 @@
 
     public void setVrMode(IBinder token, boolean enabled) throws RemoteException;
 
+    public boolean isAppForeground(int uid) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -960,4 +962,5 @@
     int SET_VR_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 359;
     int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 360;
     int CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 361;
+    int IS_APP_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 362;
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 633f699..368b8ef 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -103,6 +103,7 @@
     boolean updateAutomaticZenRule(in AutomaticZenRule automaticZenRule);
     boolean removeAutomaticZenRule(String id);
     boolean removeAutomaticZenRules(String packageName);
+    int getRuleInstanceCount(in ComponentName owner);
 
     byte[] getBackupPayload(int user);
     void applyRestore(in byte[] payload, int user);
diff --git a/core/java/android/app/JobSchedulerImpl.java b/core/java/android/app/JobSchedulerImpl.java
index 09038d5..dacf4ea 100644
--- a/core/java/android/app/JobSchedulerImpl.java
+++ b/core/java/android/app/JobSchedulerImpl.java
@@ -46,6 +46,15 @@
     }
 
     @Override
+    public int scheduleAsPackage(JobInfo job, String packageName, int userId) {
+        try {
+            return mBinder.scheduleAsPackage(job, packageName, userId);
+        } catch (RemoteException e) {
+            return JobScheduler.RESULT_FAILURE;
+        }
+    }
+
+    @Override
     public void cancel(int jobId) {
         try {
             mBinder.cancel(jobId);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 9a3c820..faf5b11 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -380,6 +380,18 @@
     }
 
     /**
+     * @hide
+     */
+    public int getRuleInstanceCount(ComponentName owner) {
+        INotificationManager service = getService();
+        try {
+            return service.getRuleInstanceCount(owner);
+        } catch (RemoteException e) {
+        }
+        return 0;
+    }
+
+    /**
      * Returns AutomaticZenRules owned by the caller.
      *
      * <p>
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 89d52f2..f3b1175 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -78,6 +78,8 @@
 import android.net.wifi.RttManager;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiScanner;
+import android.net.wifi.nan.IWifiNanManager;
+import android.net.wifi.nan.WifiNanManager;
 import android.net.wifi.p2p.IWifiP2pManager;
 import android.net.wifi.p2p.WifiP2pManager;
 import android.net.wifi.passpoint.IWifiPasspointManager;
@@ -499,6 +501,18 @@
                 return new WifiP2pManager(service);
             }});
 
+        registerService(Context.WIFI_NAN_SERVICE, WifiNanManager.class,
+                new StaticServiceFetcher<WifiNanManager>() {
+            @Override
+            public WifiNanManager createService() {
+                IBinder b = ServiceManager.getService(Context.WIFI_NAN_SERVICE);
+                IWifiNanManager service = IWifiNanManager.Stub.asInterface(b);
+                if (service == null) {
+                    return null;
+                }
+                return new WifiNanManager(service);
+            }});
+
         registerService(Context.WIFI_SCANNING_SERVICE, WifiScanner.class,
                 new CachedServiceFetcher<WifiScanner>() {
             @Override
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 13e27e2..bd10267 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -28,6 +28,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.view.IWindowManager;
 import android.view.InputEvent;
 import android.view.SurfaceControl;
@@ -167,9 +168,10 @@
             throwIfShutdownLocked();
             throwIfNotConnectedLocked();
         }
+        int callingUserId = UserHandle.getCallingUserId();
         final long identity = Binder.clearCallingIdentity();
         try {
-            IBinder token = mAccessibilityManager.getWindowToken(windowId);
+            IBinder token = mAccessibilityManager.getWindowToken(windowId, callingUserId);
             if (token == null) {
                 return false;
             }
@@ -186,9 +188,10 @@
             throwIfShutdownLocked();
             throwIfNotConnectedLocked();
         }
+        int callingUserId = UserHandle.getCallingUserId();
         final long identity = Binder.clearCallingIdentity();
         try {
-            IBinder token = mAccessibilityManager.getWindowToken(windowId);
+            IBinder token = mAccessibilityManager.getWindowToken(windowId, callingUserId);
             if (token == null) {
                 return null;
             }
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 4416415..56b4249 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -16,12 +16,16 @@
 
 package android.app;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * This class provides access to the system uimode services.  These services
  * allow applications to control UI modes of the device.
@@ -92,18 +96,26 @@
      * when the user exits desk mode.
      */
     public static String ACTION_EXIT_DESK_MODE = "android.app.action.EXIT_DESK_MODE";
-    
-    /** Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
+
+    /** @hide */
+    @IntDef({MODE_NIGHT_AUTO, MODE_NIGHT_NO, MODE_NIGHT_YES})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NightMode {}
+
+    /**
+     * Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
      * automatically switch night mode on and off based on the time.
      */
     public static final int MODE_NIGHT_AUTO = Configuration.UI_MODE_NIGHT_UNDEFINED >> 4;
     
-    /** Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
+    /**
+     * Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
      * never run in night mode.
      */
     public static final int MODE_NIGHT_NO = Configuration.UI_MODE_NIGHT_NO >> 4;
     
-    /** Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
+    /**
+     * Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
      * always run in night mode.
      */
     public static final int MODE_NIGHT_YES = Configuration.UI_MODE_NIGHT_YES >> 4;
@@ -195,20 +207,28 @@
     }
 
     /**
-     * Sets the night mode.  Changes to the night mode are only effective when
-     * the car or desk mode is enabled on a device.
-     *
-     * <p>The mode can be one of:
+     * Sets the night mode.
+     * <p>
+     * The mode can be one of:
      * <ul>
-     *   <li><em>{@link #MODE_NIGHT_NO}<em> - sets the device into notnight
-     *       mode.</li>
-     *   <li><em>{@link #MODE_NIGHT_YES}</em> - sets the device into night mode.
-     *   </li>
-     *   <li><em>{@link #MODE_NIGHT_AUTO}</em> - automatic night/notnight switching
-     *       depending on the location and certain other sensors.</li>
+     *   <li><em>{@link #MODE_NIGHT_NO}<em> sets the device into
+     *       {@code notnight} mode</li>
+     *   <li><em>{@link #MODE_NIGHT_YES}</em> sets the device into
+     *       {@code night} mode</li>
+     *   <li><em>{@link #MODE_NIGHT_AUTO}</em> automatically switches between
+     *       {@code night} and {@code notnight} based on the device's current
+     *       location and certain other sensors</li>
      * </ul>
+     * <p>
+     * <strong>Note:</strong> On API 22 and below, changes to the night mode
+     * are only effective when the {@link Configuration#UI_MODE_TYPE_CAR car}
+     * or {@link Configuration#UI_MODE_TYPE_DESK desk} mode is enabled on a
+     * device. Starting in API 23, changes to night mode are always effective.
+     *
+     * @param mode the night mode to set
+     * @see #getNightMode()
      */
-    public void setNightMode(int mode) {
+    public void setNightMode(@NightMode int mode) {
         if (mService != null) {
             try {
                 mService.setNightMode(mode);
@@ -219,11 +239,20 @@
     }
 
     /**
-     * @return the currently configured night mode. May be one of
-     *         {@link #MODE_NIGHT_NO}, {@link #MODE_NIGHT_YES},
-     *         {@link #MODE_NIGHT_AUTO}, or -1 on error.
+     * Returns the currently configured night mode.
+     * <p>
+     * May be one of:
+     * <ul>
+     *   <li>{@link #MODE_NIGHT_NO}</li>
+     *   <li>{@link #MODE_NIGHT_YES}</li>
+     *   <li>{@link #MODE_NIGHT_AUTO}</li>
+     *   <li>{@code -1} on error</li>
+     * </ul>
+     *
+     * @return the current night mode, or {@code -1} on error
+     * @see #setNightMode(int)
      */
-    public int getNightMode() {
+    public @NightMode int getNightMode() {
         if (mService != null) {
             try {
                 return mService.getNightMode();
@@ -250,9 +279,13 @@
     }
 
     /**
-     * @return If Night mode is locked or not. When Night mode is locked, changing Night mode
-     *         is only allowed to privileged system components and normal application's call
-     *         to change Night mode using {@link #setNightMode(int)} will silently fail.
+     * Returns whether night mode is locked or not.
+     * <p>
+     * When night mode is locked, only privileged system components may change
+     * night mode and calls from non-privileged applications to change night
+     * mode will fail silently.
+     *
+     * @return {@code true} if night mode is locked or {@code false} otherwise
      */
     public boolean isNightModeLocked() {
         if (mService != null) {
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 84b6d39..cfd5ca8 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -17,6 +17,7 @@
 package android.app.admin;
 
 import android.accounts.AccountManager;
+import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -29,6 +30,9 @@
 import android.os.Bundle;
 import android.security.KeyChain;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Base class for implementing a device administration component.  This
  * class provides a convenience for interpreting the raw intent actions
@@ -227,6 +231,75 @@
     public static final String ACTION_PROFILE_PROVISIONING_COMPLETE =
             "android.app.action.PROFILE_PROVISIONING_COMPLETE";
 
+    /**
+     * Action sent to a device administrator to notify that the device user
+     * has declined sharing a bugreport.
+     *
+     * <p>The calling device admin must be the device owner to receive this broadcast.
+     * @see DevicePolicyManager#requestBugreport
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_BUGREPORT_SHARING_DECLINED =
+            "android.app.action.BUGREPORT_SHARING_DECLINED";
+
+    /**
+     * Action sent to a device administrator to notify that the collection of a bugreport
+     * has failed.
+     *
+     * <p>The calling device admin must be the device owner to receive this broadcast.
+     * @see DevicePolicyManager#requestBugreport
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED";
+
+    /**
+     * Action sent to a device administrator to share the bugreport.
+     *
+     * <p>The calling device admin must be the device owner to receive this broadcast.
+     * @see DevicePolicyManager#requestBugreport
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_BUGREPORT_SHARE =
+            "android.app.action.BUGREPORT_SHARE";
+
+    /**
+     * A string containing the SHA-256 hash of the bugreport file.
+     *
+     * @see #ACTION_BUGREPORT_SHARE
+     * @hide
+     */
+    public static final String EXTRA_BUGREPORT_HASH = "android.app.extra.BUGREPORT_HASH";
+
+    /**
+     * An {@code int} failure code representing the reason of the bugreport failure.
+     *
+     * @see #ACTION_BUGREPORT_FAILED
+     * @see #BUGREPORT_FAILURE_FAILED_COMPLETING, #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
+     * @hide
+     */
+    public static final String EXTRA_BUGREPORT_FAILURE_REASON =
+            "android.app.extra.BUGREPORT_FAILURE_REASON";
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        BUGREPORT_FAILURE_FAILED_COMPLETING,
+        BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
+    })
+    /**
+     * An interface representing reason of bugreport failure.
+     *
+     * @see #EXTRA_BUGREPORT_FAILURE_REASON
+     * @hide
+     */
+    public @interface BugreportFailureCode {}
+    /** Bugreport completion process failed. */
+    public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0;
+    /** Bugreport is no longer available for collection. */
+    public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1;
+
     /** @hide */
     public static final String ACTION_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS";
 
@@ -338,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}.
@@ -482,6 +554,48 @@
     }
 
     /**
+     * Called when sharing a bugreport has been cancelled by the user of the device.
+     *
+     * <p>This callback is only applicable to device owners.
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}.
+     * @see DevicePolicyManager#requestBugreport
+     */
+    public void onBugreportSharingDeclined(Context context, Intent intent) {
+    }
+
+    /**
+     * Called when the bugreport has been shared with the device administrator app.
+     *
+     * <p>This callback is only applicable to device owners.
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}. Contains the URI of
+     * the bugreport file (with MIME type "application/vnd.android.bugreport"), that can be accessed
+     * by calling {@link Intent#getData()}
+     * @param bugreportHash SHA-256 hash of the bugreport file.
+     * @see DevicePolicyManager#requestBugreport
+     */
+    public void onBugreportShared(Context context, Intent intent, String bugreportHash) {
+    }
+
+    /**
+     * Called when the bugreport collection flow has failed.
+     *
+     * <p>This callback is only applicable to device owners.
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}.
+     * @param failureCode int containing failure code. One of
+     * #BUGREPORT_FAILURE_FAILED_COMPLETING or #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
+     * @see DevicePolicyManager#requestBugreport
+     */
+    public void onBugreportFailed(Context context, Intent intent,
+            @BugreportFailureCode int failureCode) {
+    }
+
+    /**
      * Intercept standard device administrator broadcasts.  Implementations
      * should not override this method; it is better to implement the
      * convenience callbacks for each action.
@@ -524,6 +638,15 @@
         } else if (ACTION_NOTIFY_PENDING_SYSTEM_UPDATE.equals(action)) {
             long receivedTime = intent.getLongExtra(EXTRA_SYSTEM_UPDATE_RECEIVED_TIME, -1);
             onSystemUpdatePending(context, intent, receivedTime);
+        } else if (ACTION_BUGREPORT_SHARING_DECLINED.equals(action)) {
+            onBugreportSharingDeclined(context, intent);
+        } else if (ACTION_BUGREPORT_SHARE.equals(action)) {
+            String bugreportFileHash = intent.getStringExtra(EXTRA_BUGREPORT_HASH);
+            onBugreportShared(context, intent, bugreportFileHash);
+        } else if (ACTION_BUGREPORT_FAILED.equals(action)) {
+            int failureCode = intent.getIntExtra(EXTRA_BUGREPORT_FAILURE_REASON,
+                    BUGREPORT_FAILURE_FAILED_COMPLETING);
+            onBugreportFailed(context, intent, failureCode);
         }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4de3ceb..0161119 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -620,6 +620,21 @@
             "android.app.extra.PROVISIONING_LOGO_URI";
 
     /**
+     * A boolean extra indicating if user setup should be skipped, for when provisioning is started
+     * during setup-wizard.
+     *
+     * <p>If unspecified, defaults to {@code true} to match the behavior in
+     * {@link android.os.Build.VERSION_CODES#M} and earlier.
+     *
+     * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE} or
+     * {@link #ACTION_PROVISION_MANAGED_USER}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_PROVISIONING_SKIP_USER_SETUP =
+            "android.app.extra.PROVISIONING_SKIP_USER_SETUP";
+
+    /**
      * This MIME type is used for starting the Device Owner provisioning.
      *
      * <p>During device owner provisioning a device admin app is set as the owner of the device.
@@ -758,12 +773,28 @@
      * have the user select a new password in order to meet the current
      * constraints. Upon being resumed from this activity, you can check the new
      * password characteristics to see if they are sufficient.
+     *
+     * If the intent is launched from within a managed profile with a profile
+     * owner built against {@link android.os.Build.VERSION_CODES#M} or before,
+     * this will trigger entering a new password for the parent of the profile.
+     * For all other cases it will trigger entering a new password for the user
+     * or profile it is launched from.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_SET_NEW_PASSWORD
             = "android.app.action.SET_NEW_PASSWORD";
 
     /**
+     * Activity action: have the user enter a new password for the parent profile.
+     * If the intent is launched from within a managed profile, this will trigger
+     * entering a new password for the parent of the profile. In all other cases
+     * the behaviour is identical to {@link #ACTION_SET_NEW_PASSWORD}.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_SET_NEW_PARENT_PROFILE_PASSWORD
+            = "android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD";
+
+    /**
      * Flag used by {@link #addCrossProfileIntentFilter} to allow activities in
      * the parent profile to access intents sent from the managed profile.
      * That is, when an app in the managed profile calls
@@ -941,6 +972,22 @@
     }
 
     /**
+     * Returns true if the Profile Challenge is available to use for the given profile user.
+     *
+     * @hide
+     */
+    public boolean isSeparateProfileChallengeAllowed(int userHandle) {
+        if (mService != null) {
+            try {
+                return mService.isSeparateProfileChallengeAllowed(userHandle);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+        return false;
+    }
+
+    /**
      * Constant for {@link #setPasswordQuality}: the policy has no requirements
      * for the password.  Note that quality constants are ordered so that higher
      * values are more restrictive.
@@ -1006,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
@@ -2420,6 +2479,53 @@
     }
 
     /**
+     * Called by a device or profile owner to configure an always-on VPN connection through a
+     * specific application for the current user.
+     * This connection is automatically granted and persisted after a reboot.
+     *
+     * <p>The designated package should declare a {@link android.net.VpnService} in its
+     *    manifest guarded by {@link android.Manifest.permission#BIND_VPN_SERVICE},
+     *    otherwise the call will fail.
+     *
+     * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
+     *                   to remove an existing always-on VPN configuration.
+     *
+     * @return {@code true} if the package is set as always-on VPN controller;
+     *         {@code false} otherwise.
+     */
+    public boolean setAlwaysOnVpnPackage(@NonNull ComponentName admin,
+            @Nullable String vpnPackage) {
+        if (mService != null) {
+            try {
+                return mService.setAlwaysOnVpnPackage(admin, vpnPackage);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by a device or profile owner to read the name of the package administering an
+     * always-on VPN connection for the current user.
+     * If there is no such package, or the always-on VPN is provided by the system instead
+     * of by an application, {@code null} will be returned.
+     *
+     * @return Package name of VPN controller responsible for always-on VPN,
+     *         or {@code null} if none is set.
+     */
+    public String getAlwaysOnVpnPackage(@NonNull ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.getAlwaysOnVpnPackage(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+        return null;
+    }
+
+    /**
      * Called by an application that is administering the device to disable all cameras
      * on the device, for this user. After setting this, no applications running as this user
      * will be able to access any cameras on the device.
@@ -2466,6 +2572,28 @@
     }
 
     /**
+     * Called by a device owner to request a bugreport.
+     *
+     * <p>There must be only one user on the device, managed by the device owner.
+     * Otherwise a security exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return {@code true} if the bugreport collection started successfully, or {@code false}
+     * if it wasn't triggered because a previous bugreport operation is still active
+     * (either the bugreport is still running or waiting for the user to share or decline)
+     */
+    public boolean requestBugreport(@NonNull ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.requestBugreport(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+        return false;
+    }
+
+    /**
      * Determine whether or not creating a guest user has been disabled for the device
      *
      * @hide
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index d3c32c5..08cab88 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -91,6 +91,8 @@
     boolean getStorageEncryption(in ComponentName who, int userHandle);
     int getStorageEncryptionStatus(int userHandle);
 
+    boolean requestBugreport(in ComponentName who);
+
     void setCameraDisabled(in ComponentName who, boolean disabled);
     boolean getCameraDisabled(in ComponentName who, int userHandle);
 
@@ -144,6 +146,9 @@
     void setCertInstallerPackage(in ComponentName who, String installerPackage);
     String getCertInstallerPackage(in ComponentName who);
 
+    boolean setAlwaysOnVpnPackage(in ComponentName who, String vpnPackage);
+    String getAlwaysOnVpnPackage(in ComponentName who);
+
     void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
     void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
 
@@ -256,4 +261,6 @@
 
     String getShortSupportMessageForUser(in ComponentName admin, int userHandle);
     String getLongSupportMessageForUser(in ComponentName admin, int userHandle);
+
+    boolean isSeparateProfileChallengeAllowed(int userHandle);
 }
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/job/IJobScheduler.aidl b/core/java/android/app/job/IJobScheduler.aidl
index f1258ae..f0c3302 100644
--- a/core/java/android/app/job/IJobScheduler.aidl
+++ b/core/java/android/app/job/IJobScheduler.aidl
@@ -24,6 +24,7 @@
   */
 interface IJobScheduler {
     int schedule(in JobInfo job);
+    int scheduleAsPackage(in JobInfo job, String packageName, int userId);
     void cancel(int jobId);
     void cancelAll();
     List<JobInfo> getAllPendingJobs();
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index b899710..9ad35d4 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -91,6 +91,7 @@
     private final long flexMillis;
     private final long initialBackoffMillis;
     private final int backoffPolicy;
+    private final int priority;
 
     /**
      * Unique job id associated with this class. This is assigned to your job by the scheduler.
@@ -113,6 +114,11 @@
         return service;
     }
 
+    /** @hide */
+    public int getPriority() {
+        return priority;
+    }
+
     /**
      * Whether this job needs the device to be plugged in.
      */
@@ -237,6 +243,7 @@
         backoffPolicy = in.readInt();
         hasEarlyConstraint = in.readInt() == 1;
         hasLateConstraint = in.readInt() == 1;
+        priority = in.readInt();
     }
 
     private JobInfo(JobInfo.Builder b) {
@@ -256,6 +263,7 @@
         backoffPolicy = b.mBackoffPolicy;
         hasEarlyConstraint = b.mHasEarlyConstraint;
         hasLateConstraint = b.mHasLateConstraint;
+        priority = b.mPriority;
     }
 
     @Override
@@ -281,6 +289,7 @@
         out.writeInt(backoffPolicy);
         out.writeInt(hasEarlyConstraint ? 1 : 0);
         out.writeInt(hasLateConstraint ? 1 : 0);
+        out.writeInt(priority);
     }
 
     public static final Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
@@ -305,6 +314,7 @@
         private int mJobId;
         private PersistableBundle mExtras = PersistableBundle.EMPTY;
         private ComponentName mJobService;
+        private int mPriority;
         // Requirements.
         private boolean mRequiresCharging;
         private boolean mRequiresDeviceIdle;
@@ -338,6 +348,14 @@
         }
 
         /**
+         * @hide
+         */
+        public Builder setPriority(int priority) {
+            mPriority = priority;
+            return this;
+        }
+
+        /**
          * Set optional extras. This is persisted, so we only allow primitive types.
          * @param extras Bundle containing extras you want the scheduler to hold on to for you.
          */
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index 7ee39f5..a0a60e8 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -28,10 +28,22 @@
  */
 public class JobParameters implements Parcelable {
 
+    /** @hide */
+    public static final int REASON_CANCELED = 0;
+    /** @hide */
+    public static final int REASON_CONSTRAINTS_NOT_SATISFIED = 1;
+    /** @hide */
+    public static final int REASON_PREEMPT = 2;
+    /** @hide */
+    public static final int REASON_TIMEOUT = 3;
+    /** @hide */
+    public static final int REASON_DEVICE_IDLE = 4;
+
     private final int jobId;
     private final PersistableBundle extras;
     private final IBinder callback;
     private final boolean overrideDeadlineExpired;
+    private int stopReason; // Default value of stopReason is REASON_CANCELED
 
     /** @hide */
     public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
@@ -50,6 +62,14 @@
     }
 
     /**
+     * Reason onStopJob() was called on this job.
+     * @hide
+     */
+    public int getStopReason() {
+        return stopReason;
+    }
+
+    /**
      * @return The extras you passed in when constructing this job with
      * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will
      * never be null. If you did not set any extras this will be an empty bundle.
@@ -78,6 +98,12 @@
         extras = in.readPersistableBundle();
         callback = in.readStrongBinder();
         overrideDeadlineExpired = in.readInt() == 1;
+        stopReason = in.readInt();
+    }
+
+    /** @hide */
+    public void setStopReason(int reason) {
+        stopReason = reason;
     }
 
     @Override
@@ -91,6 +117,7 @@
         dest.writePersistableBundle(extras);
         dest.writeStrongBinder(callback);
         dest.writeInt(overrideDeadlineExpired ? 1 : 0);
+        dest.writeInt(stopReason);
     }
 
     public static final Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
index 6e96da5..5e1a4256 100644
--- a/core/java/android/app/job/JobScheduler.java
+++ b/core/java/android/app/job/JobScheduler.java
@@ -63,6 +63,17 @@
     public abstract int schedule(JobInfo job);
 
     /**
+     *
+     * @param job The job to be scheduled.
+     * @param packageName The package on behalf of which the job is to be scheduled. This will be
+     *                    used to track battery usage and appIdleState.
+     * @param userId    User on behalf of whom this job is to be scheduled.
+     * @return {@link #RESULT_SUCCESS} or {@link #RESULT_FAILURE}
+     * @hide
+     */
+    public abstract int scheduleAsPackage(JobInfo job, String packageName, int userId);
+
+    /**
      * Cancel a job that is pending in the JobScheduler.
      * @param jobId unique identifier for this job. Obtain this value from the jobs returned by
      * {@link #getAllPendingJobs()}.
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index ee591d3..88ba874 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -16,7 +16,9 @@
 
 package android.app.trust;
 
+import android.Manifest;
 import android.annotation.IntDef;
+import android.annotation.RequiresPermission;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -54,9 +56,12 @@
      * Changes the lock status for the given user. This is only applicable to Managed Profiles,
      * other users should be handled by Keyguard.
      *
+     * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+     *
      * @param userId The id for the user to be locked/unlocked.
      * @param locked The value for that user's locked state.
      */
+    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
     public void setDeviceLockedForUser(int userId, boolean locked) {
         try {
             mService.setDeviceLockedForUser(userId, locked);
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/auditing/SecurityLog.java b/core/java/android/auditing/SecurityLog.java
new file mode 100644
index 0000000..87dc1d8
--- /dev/null
+++ b/core/java/android/auditing/SecurityLog.java
@@ -0,0 +1,210 @@
+/*
+ * 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.auditing;
+
+import android.annotation.IntDef;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemProperties;
+import android.util.EventLog.Event;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
+
+public class SecurityLog {
+
+    private static final String PROPERTY_LOGGING_ENABLED = "persist.logd.security";
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({TAG_ADB_SHELL_INTERACTIVE, TAG_ADB_SHELL_CMD, TAG_SYNC_RECV_FILE, TAG_SYNC_SEND_FILE,
+        TAG_APP_PROCESS_START, TAG_DEVICE_UNLOCK_ATTEMPT, TAG_DEVICE_LOCKED})
+    public @interface SECURITY_LOG_TAG {}
+
+    /**
+     * Indicate that an ADB interactive shell was opened via "adb shell".
+     * There is no extra payload in the log event.
+     */
+    public static final int TAG_ADB_SHELL_INTERACTIVE =
+            SecurityLogTags.SECURITY_ADB_SHELL_INTERACTIVE;
+    /**
+     * Indicate that an shell command was issued over ADB via "adb shell command"
+     * The log entry contains a string data of the shell command, accessible via
+     * {@link SecurityEvent#getData()}
+     */
+    public static final int TAG_ADB_SHELL_CMD = SecurityLogTags.SECURITY_ADB_SHELL_COMMAND;
+    /**
+     * Indicate that a file was pulled from the device via the adb daemon, for example via
+     * "adb pull". The log entry contains a string data of the path of the pulled file,
+     * accessible via {@link SecurityEvent#getData()}
+     */
+    public static final int TAG_SYNC_RECV_FILE = SecurityLogTags.SECURITY_ADB_SYNC_RECV;
+    /**
+     * Indicate that a file was pushed to the device via the adb daemon, for example via
+     * "adb push". The log entry contains a string data of the destination path of the
+     * pushed file, accessible via {@link SecurityEvent#getData()}
+     */
+    public static final int TAG_SYNC_SEND_FILE = SecurityLogTags.SECURITY_ADB_SYNC_SEND;
+    /**
+     * Indicate that an app process was started. The log entry contains the following
+     * information about the process in order, accessible via {@link SecurityEvent#getData()}}:
+     * process name (String), exact start time (long), app Uid (integer), app Pid (integer),
+     * seinfo tag (String), SHA-256 hash of the APK in hexadecimal (String)
+     */
+    public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START;
+
+    /**
+     * Indicate that there has been an attempt to unlock the device. The log entry contains the
+     * following information about the attempt in order, accessible via
+     * {@link SecurityEvent#getData()}}: unlock result (integer, 1 for successful unlock, 0 for
+     * unsuccessful), unlock method (String)
+     */
+    public static final int TAG_DEVICE_UNLOCK_ATTEMPT =
+            SecurityLogTags.SECURITY_DEVICE_UNLOCK_ATTEMPT;
+
+    /**
+     * Indicate that the device has been locked, either by user or by timeout.
+     */
+    public static final int TAG_DEVICE_LOCKED = SecurityLogTags.SECURITY_DEVICE_LOCKED;
+
+
+    /**
+     * Returns if device logging is enabled. Log producers should only write new logs if this is
+     * true. Under the hood this is the logical AND of whether device owner exists and whether
+     * it enables logging by setting the system property {@link #PROPERTY_LOGGING_ENABLED}.
+     * @hide
+     */
+    public static native boolean isLoggingEnabled();
+
+    /**
+     * @hide
+     */
+    public static void setLoggingEnabledProperty(boolean enabled) {
+        SystemProperties.set(PROPERTY_LOGGING_ENABLED, enabled ? "true" : "false");
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean getLoggingEnabledProperty() {
+        return SystemProperties.getBoolean(PROPERTY_LOGGING_ENABLED, false);
+    }
+
+    /**
+     * A class representing a security event log entry.
+     */
+    public static class SecurityEvent implements Parcelable {
+        private Event mEvent;
+
+        /** @hide */
+        /*package*/ SecurityEvent(byte[] data) {
+            mEvent = Event.fromBytes(data);
+        }
+
+        /**
+         * Returns the timestamp in nano seconds when this event was logged.
+         */
+        public long getTimeNanos() {
+            return mEvent.getTimeNanos();
+        }
+
+        /**
+         * Returns the tag of this log entry, which specifies entry's semantics.
+         * Could be one of {@link SecurityLog#TAG_SYNC_RECV_FILE},
+         * {@link SecurityLog#TAG_SYNC_SEND_FILE}, {@link SecurityLog#TAG_ADB_SHELL_CMD},
+         * {@link SecurityLog#TAG_ADB_SHELL_INTERACTIVE}, {@link SecurityLog#TAG_APP_PROCESS_START}.
+         */
+        public @SECURITY_LOG_TAG int getTag() {
+            return mEvent.getTag();
+        }
+
+        /**
+         * Returns the payload contained in this log. Each call to this method will
+         * retrieve the next payload item. If no more payload exists, it returns {@code null}.
+         */
+        public Object getData() {
+            return mEvent.getData();
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeByteArray(mEvent.getBytes());
+        }
+
+        public static final Parcelable.Creator<SecurityEvent> CREATOR =
+                new Parcelable.Creator<SecurityEvent>() {
+            @Override
+            public SecurityEvent createFromParcel(Parcel source) {
+                return new SecurityEvent(source.createByteArray());
+            }
+
+            @Override
+            public SecurityEvent[] newArray(int size) {
+                return new SecurityEvent[size];
+            }
+        };
+    }
+    /**
+     * Retrieve all security logs and return immediately.
+     * @hide
+     */
+    public static native void readEvents(Collection<SecurityEvent> output) throws IOException;
+
+    /**
+     * Retrieve all security logs since the given timestamp in nanoseconds and return immediately.
+     * @hide
+     */
+    public static native void readEventsSince(long timestamp, Collection<SecurityEvent> output)
+            throws IOException;
+
+    /**
+     * Retrieve all security logs before the last reboot. May return corrupted data due to
+     * unreliable pstore.
+     * @hide
+     */
+    public static native void readPreviousEvents(Collection<SecurityEvent> output)
+            throws IOException;
+
+    /**
+     * Retrieve all security logs whose timestamp (in nanosceonds) is equal to or greater than the
+     * given timestamp. This method will block until either the last log earlier than the given
+     * timestamp is about to be pruned, or after a 2-hour timeout has passed.
+     * @hide
+     */
+    public static native void readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output)
+            throws IOException;
+
+    /**
+     * Write a log entry to the underlying storage, with a string payload.
+     * @hide
+     */
+    public static native int writeEvent(int tag, String str);
+
+    /**
+     * Write a log entry to the underlying storage, with several payloads.
+     * Supported types of payload are: integer, long, float, string plus array of supported types.
+     * @hide
+     */
+    public static native int writeEvent(int tag, Object... payloads);
+}
diff --git a/core/java/android/auditing/SecurityLogTags.logtags b/core/java/android/auditing/SecurityLogTags.logtags
new file mode 100644
index 0000000..455acff
--- /dev/null
+++ b/core/java/android/auditing/SecurityLogTags.logtags
@@ -0,0 +1,11 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package android.auditing
+
+210001 security_adb_shell_interactive
+210002 security_adb_shell_command        (command|3)
+210003 security_adb_sync_recv            (path|3)
+210004 security_adb_sync_send            (path|3)
+210005 security_app_process_start        (process|3),(start_time|2|3),(uid|1),(pid|1),(seinfo|3),(sha256|3)
+210006 security_device_unlock_attempt    (success|1),(method|3)
+210007 security_device_locked
\ No newline at end of file
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
old mode 100644
new mode 100755
index 2e27345..74302f2
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -371,6 +371,89 @@
     }
 
     /**
+     * Set priority of the profile
+     *
+     * <p> The device should already be paired.
+     *  Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
+     * {@link #PRIORITY_OFF},
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Paired bluetooth device
+     * @param priority
+     * @return true if priority is set, false on error
+     * @hide
+     */
+    public boolean setPriority(BluetoothDevice device, int priority) {
+        if (DBG) log("setPriority(" + device + ", " + priority + ")");
+        if (mService != null && isEnabled()
+            && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF &&
+                priority != BluetoothProfile.PRIORITY_ON){
+                return false;
+            }
+            try {
+                return mService.setPriority(device, priority);
+            } catch (RemoteException e) {
+                   Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                   return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+            return false;
+    }
+
+    /**
+     * Get the priority of the profile.
+     *
+     * <p> The priority can be any of:
+     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
+     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device Bluetooth device
+     * @return priority of the device
+     * @hide
+     */
+    public int getPriority(BluetoothDevice device) {
+        if (VDBG) log("getPriority(" + device + ")");
+        if (mService != null && isEnabled()
+            && isValidDevice(device)) {
+            try {
+                return mService.getPriority(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.PRIORITY_OFF;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.PRIORITY_OFF;
+    }
+
+    /**
+     * Check if A2DP profile is streaming music.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device BluetoothDevice device
+     */
+    public boolean isA2dpPlaying(BluetoothDevice device) {
+        if (mService != null && isEnabled()
+            && isValidDevice(device)) {
+            try {
+                return mService.isA2dpPlaying(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
      * Helper for converting a state to a string.
      *
      * For debug use only - strings are not internationalized.
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/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index b53a8fc..444e429 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.media.MediaMetadata;
+import android.media.session.PlaybackState;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
@@ -28,8 +30,8 @@
 import java.util.List;
 
 /**
- * This class provides the public APIs to control the Bluetooth AVRCP Controller
- * profile.
+ * This class provides the public APIs to control the Bluetooth AVRCP Controller. It currently
+ * supports player information, playback support and track metadata.
  *
  *<p>BluetoothAvrcpController is a proxy object for controlling the Bluetooth AVRCP
  * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
@@ -39,7 +41,7 @@
  */
 public final class BluetoothAvrcpController implements BluetoothProfile {
     private static final String TAG = "BluetoothAvrcpController";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false;
 
     /**
@@ -61,7 +63,63 @@
      * receive.
      */
     public static final String ACTION_CONNECTION_STATE_CHANGED =
-        "android.bluetooth.acrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
+        "android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
+
+    /**
+     * Intent used to broadcast the change in metadata state of playing track on the AVRCP
+     * AG.
+     *
+     * <p>This intent will have the two extras:
+     * <ul>
+     *    <li> {@link #EXTRA_METADATA} - {@link MediaMetadata} containing the current metadata.</li>
+     *    <li> {@link #EXTRA_PLAYBACK} - {@link PlaybackState} containing the current playback
+     *    state. </li>
+     * </ul>
+     */
+    public static final String ACTION_TRACK_EVENT =
+        "android.bluetooth.avrcp-controller.profile.action.TRACK_EVENT";
+
+
+    /**
+     * Intent used to broadcast the change in player application setting state on AVRCP AG.
+     *
+     * <p>This intent will have the following extras:
+     * <ul>
+     *    <li> {@link #EXTRA_PLAYER_SETTING} - {@link BluetoothAvrcpPlayerSettings} containing the
+     *    most recent player setting. </li>
+     * </ul>
+     */
+    public static final String ACTION_PLAYER_SETTING =
+        "android.bluetooth.avrcp-controller.profile.action.PLAYER_SETTING";
+
+    public static final String EXTRA_METADATA =
+            "android.bluetooth.avrcp-controller.profile.extra.METADATA";
+
+    public static final String EXTRA_PLAYBACK =
+            "android.bluetooth.avrcp-controller.profile.extra.PLAYBACK";
+
+    public static final String EXTRA_PLAYER_SETTING =
+            "android.bluetooth.avrcp-controller.profile.extra.PLAYER_SETTING";
+
+    /*
+     * KeyCoded for Pass Through Commands
+     */
+    public static final int PASS_THRU_CMD_ID_PLAY = 0x44;
+    public static final int PASS_THRU_CMD_ID_PAUSE = 0x46;
+    public static final int PASS_THRU_CMD_ID_VOL_UP = 0x41;
+    public static final int PASS_THRU_CMD_ID_VOL_DOWN = 0x42;
+    public static final int PASS_THRU_CMD_ID_STOP = 0x45;
+    public static final int PASS_THRU_CMD_ID_FF = 0x49;
+    public static final int PASS_THRU_CMD_ID_REWIND = 0x48;
+    public static final int PASS_THRU_CMD_ID_FORWARD = 0x4B;
+    public static final int PASS_THRU_CMD_ID_BACKWARD = 0x4C;
+    /* Key State Variables */
+    public static final int KEY_STATE_PRESSED = 0;
+    public static final int KEY_STATE_RELEASED = 1;
+    /* Group Navigation Key Codes */
+    public static final int PASS_THRU_CMD_ID_NEXT_GRP = 0x00;
+    public static final int PASS_THRU_CMD_ID_PREV_GRP = 0x01;
+
 
     private Context mContext;
     private ServiceListener mServiceListener;
@@ -69,33 +127,33 @@
     private BluetoothAdapter mAdapter;
 
     final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
-            new IBluetoothStateChangeCallback.Stub() {
-                public void onBluetoothStateChange(boolean up) {
-                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
-                    if (!up) {
-                        if (VDBG) Log.d(TAG,"Unbinding service...");
-                        synchronized (mConnection) {
-                            try {
-                                mService = null;
-                                mContext.unbindService(mConnection);
-                            } catch (Exception re) {
-                                Log.e(TAG,"",re);
-                            }
+        new IBluetoothStateChangeCallback.Stub() {
+            public void onBluetoothStateChange(boolean up) {
+                if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                if (!up) {
+                    if (VDBG) Log.d(TAG,"Unbinding service...");
+                    synchronized (mConnection) {
+                        try {
+                            mService = null;
+                            mContext.unbindService(mConnection);
+                        } catch (Exception re) {
+                            Log.e(TAG,"",re);
                         }
-                    } else {
-                        synchronized (mConnection) {
-                            try {
-                                if (mService == null) {
-                                    if (VDBG) Log.d(TAG,"Binding service...");
-                                    doBind();
-                                }
-                            } catch (Exception re) {
-                                Log.e(TAG,"",re);
+                    }
+                } else {
+                    synchronized (mConnection) {
+                        try {
+                            if (mService == null) {
+                                if (VDBG) Log.d(TAG,"Binding service...");
+                                doBind();
                             }
+                        } catch (Exception re) {
+                            Log.e(TAG,"",re);
                         }
                     }
                 }
-        };
+            }
+      };
 
     /**
      * Create a BluetoothAvrcpController proxy object for interacting with the local
@@ -223,6 +281,104 @@
         if (mService == null) Log.w(TAG, "Proxy not attached to service");
     }
 
+    /**
+     * Gets the player application settings.
+     *
+     * @return the {@link BluetoothAvrcpPlayerSettings} or {@link null} if there is an error.
+     */
+    public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "getPlayerSettings");
+        BluetoothAvrcpPlayerSettings settings = null;
+        if (mService != null && isEnabled()) {
+            try {
+                settings = mService.getPlayerSettings(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in getMetadata() " + e);
+                return null;
+            }
+        }
+        return settings;
+    }
+
+    /**
+     * Gets the metadata for the current track.
+     *
+     * This should be usually called when application UI needs to be updated, eg. when the track
+     * changes or immediately after connecting and getting the current state.
+     * @return the {@link MediaMetadata} or {@link null} if there is an error.
+     */
+    public MediaMetadata getMetadata(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "getMetadata");
+        MediaMetadata metadata = null;
+        if (mService != null && isEnabled()) {
+            try {
+                metadata = mService.getMetadata(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in getMetadata() " + e);
+                return null;
+            }
+        }
+        return metadata;
+    }
+
+    /**
+     * Gets the playback state for current track.
+     *
+     * When the application is first connecting it can use current track state to get playback info.
+     * For all further updates it should listen to notifications.
+     * @return the {@link PlaybackState} or {@link null} if there is an error.
+     */
+    public PlaybackState getPlaybackState(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "getPlaybackState");
+        PlaybackState playbackState = null;
+        if (mService != null && isEnabled()) {
+            try {
+                playbackState = mService.getPlaybackState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,
+                    "Error talking to BT service in getPlaybackState() " + e);
+                return null;
+            }
+        }
+        return playbackState;
+    }
+
+    /**
+     * Sets the player app setting for current player.
+     * returns true in case setting is supported by remote, false otherwise
+     */
+    public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
+        if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.setPlayerApplicationSetting(plAppSetting);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in setPlayerApplicationSetting() " + e);
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /*
+     * Send Group Navigation Command to Remote.
+     * possible keycode values: next_grp, previous_grp defined above
+     */
+    public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
+        Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = " + keyState);
+        if (mService != null && isEnabled()) {
+            try {
+                mService.sendGroupNavigationCmd(device, keyCode, keyState);
+                return;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in sendGroupNavigationCmd()", e);
+                return;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+    }
+
     private final ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl b/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
new file mode 100644
index 0000000..590fd63
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothAvrcpPlayerSettings;
diff --git a/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java b/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java
new file mode 100644
index 0000000..927cb56
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAvrcpPlayerSettings.java
@@ -0,0 +1,189 @@
+/*
+ * 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;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class used to identify settings associated with the player on AG.
+ *
+ * {@hide}
+ */
+public final class BluetoothAvrcpPlayerSettings implements Parcelable {
+    public static final String TAG = "BluetoothAvrcpPlayerSettings";
+
+    /**
+     * Equalizer setting.
+     */
+    public static final int SETTING_EQUALIZER    = 0x01;
+
+    /**
+     * Repeat setting.
+     */
+    public static final int SETTING_REPEAT       = 0x02;
+
+    /**
+     * Shuffle setting.
+     */
+    public static final int SETTING_SHUFFLE      = 0x04;
+
+    /**
+     * Scan mode setting.
+     */
+    public static final int SETTING_SCAN         = 0x08;
+
+    /**
+     * Invalid state.
+     *
+     * Used for returning error codes.
+     */
+    public static final int STATE_INVALID = -1;
+
+    /**
+     * OFF state.
+     *
+     * Denotes a general OFF state. Applies to all settings.
+     */
+    public static final int STATE_OFF = 0x00;
+
+    /**
+     * ON state.
+     *
+     * Applies to {@link SETTING_EQUALIZER}.
+     */
+    public static final int STATE_ON = 0x01;
+
+    /**
+     * Single track repeat.
+     *
+     * Applies only to {@link SETTING_REPEAT}.
+     */
+    public static final int STATE_SINGLE_TRACK = 0x02;
+
+    /**
+     * All track repeat/shuffle.
+     *
+     * Applies to {@link SETTING_REPEAT}, {@link SETTING_SHUFFLE} and {@link SETTING_SCAN}.
+     */
+    public static final int STATE_ALL_TRACK    = 0x03;
+
+    /**
+     * Group repeat/shuffle.
+     *
+     * Applies to {@link SETTING_REPEAT}, {@link SETTING_SHUFFLE} and {@link SETTING_SCAN}.
+     */
+    public static final int STATE_GROUP        = 0x04;
+
+    /**
+     * List of supported settings ORed.
+     */
+    private int mSettings;
+
+    /**
+     * Hash map of current capability values.
+     */
+    private Map<Integer, Integer> mSettingsValue = new HashMap<Integer, Integer>();
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mSettings);
+        out.writeInt(mSettingsValue.size());
+        for (int k : mSettingsValue.keySet()) {
+            out.writeInt(k);
+            out.writeInt(mSettingsValue.get(k));
+        }
+    }
+
+    public static final Parcelable.Creator<BluetoothAvrcpPlayerSettings> CREATOR
+            = new Parcelable.Creator<BluetoothAvrcpPlayerSettings>() {
+        public BluetoothAvrcpPlayerSettings createFromParcel(Parcel in) {
+            return new BluetoothAvrcpPlayerSettings(in);
+        }
+
+        public BluetoothAvrcpPlayerSettings[] newArray(int size) {
+            return new BluetoothAvrcpPlayerSettings[size];
+        }
+    };
+
+    private BluetoothAvrcpPlayerSettings(Parcel in) {
+        mSettings = in.readInt();
+        int numSettings = in.readInt();
+        for (int i = 0; i < numSettings; i++) {
+            mSettingsValue.put(in.readInt(), in.readInt());
+        }
+    }
+
+    /**
+     * Create a new player settings object.
+     *
+     * @param settings a ORed value of SETTINGS_* defined above.
+     */
+    public BluetoothAvrcpPlayerSettings(int settings) {
+        mSettings = settings;
+    }
+
+    /**
+     * Get the supported settings.
+     *
+     * @return int ORed value of supported settings.
+     */
+    public int getSettings() {
+        return mSettings;
+    }
+
+    /**
+     * Add a setting value.
+     *
+     * The setting must be part of possible settings in {@link getSettings()}.
+     * @param setting setting config.
+     * @param value value for the setting.
+     * @throws IllegalStateException if the setting is not supported.
+     */
+    public void addSettingValue(int setting, int value) {
+        if ((setting & mSettings) == 0) {
+            Log.e(TAG, "Setting not supported: " + setting + " " + mSettings);
+            throw new IllegalStateException("Setting not supported: " + setting);
+        }
+        mSettingsValue.put(setting, value);
+    }
+
+    /**
+     * Get a setting value.
+     *
+     * The setting must be part of possible settings in {@link getSettings()}.
+     * @param setting setting config.
+     * @return value value for the setting.
+     * @throws IllegalStateException if the setting is not supported.
+     */
+    public int getSettingValue(int setting) {
+        if ((setting & mSettings) == 0) {
+            Log.e(TAG, "Setting not supported: " + setting + " " + mSettings);
+            throw new IllegalStateException("Setting not supported: " + setting);
+        }
+        Integer i = mSettingsValue.get(setting);
+        if (i == null) return -1;
+        return i;
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
old mode 100644
new mode 100755
index 54bf4af..4a38287
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -283,6 +283,8 @@
     public static final int PROFILE_PANU = 4;
     /** @hide */
     public static final int PROFILE_NAP = 5;
+    /** @hide */
+    public static final int PROFILE_A2DP_SINK = 6;
 
     /**
      * Check class bits for possible bluetooth profile support.
@@ -310,6 +312,21 @@
                 default:
                     return false;
             }
+        } else if (profile == PROFILE_A2DP_SINK) {
+            if (hasService(Service.CAPTURE)) {
+                return true;
+            }
+            // By the A2DP spec, srcs must indicate the CAPTURE service.
+            // However if some device that do not, we try to
+            // match on some other class bits.
+            switch (getDeviceClass()) {
+                case Device.AUDIO_VIDEO_HIFI_AUDIO:
+                case Device.AUDIO_VIDEO_SET_TOP_BOX:
+                case Device.AUDIO_VIDEO_VCR :
+                    return true;
+                default:
+                    return false;
+            }
         } else if (profile == PROFILE_HEADSET) {
             // The render service class is required by the spec for HFP, so is a
             // pretty good signal
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index cd5c205..f43fb30 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -879,18 +879,16 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
-     * @param hash - Simple Secure pairing hash
-     * @param randomizer - The random key obtained using OOB
+     * @param transport - Transport to use
+     * @param oobData - Out Of Band data
      * @return false on immediate error, true if bonding will begin
      *
      * @hide
      */
-    public boolean createBondOutOfBand(byte[] hash, byte[] randomizer) {
-        //TODO(BT)
-        /*
+    public boolean createBondOutOfBand(int transport, OobData oobData) {
         try {
-            return sService.createBondOutOfBand(this, hash, randomizer);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
+            return sService.createBondOutOfBand(this, transport, oobData);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
 
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 66f3418..74cb0f6 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -20,6 +20,7 @@
 import android.bluetooth.IBluetoothStateChangeCallback;
 import android.bluetooth.BluetoothActivityEnergyInfo;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.OobData;
 import android.os.ParcelUuid;
 import android.os.ParcelFileDescriptor;
 
@@ -56,6 +57,7 @@
 
     BluetoothDevice[] getBondedDevices();
     boolean createBond(in BluetoothDevice device, in int transport);
+    boolean createBondOutOfBand(in BluetoothDevice device, in int transport, in OobData oobData);
     boolean cancelBondProcess(in BluetoothDevice device);
     boolean removeBond(in BluetoothDevice device);
     int getBondState(in BluetoothDevice device);
diff --git a/core/java/android/bluetooth/IBluetoothA2dpSink.aidl b/core/java/android/bluetooth/IBluetoothA2dpSink.aidl
old mode 100644
new mode 100755
index b7c6476..d1458246
--- a/core/java/android/bluetooth/IBluetoothA2dpSink.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dpSink.aidl
@@ -31,4 +31,7 @@
     List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
     int getConnectionState(in BluetoothDevice device);
     BluetoothAudioConfig getAudioConfig(in BluetoothDevice device);
+    boolean setPriority(in BluetoothDevice device, int priority);
+    int getPriority(in BluetoothDevice device);
+    boolean isA2dpPlaying(in BluetoothDevice device);
 }
diff --git a/core/java/android/bluetooth/IBluetoothAvrcpController.aidl b/core/java/android/bluetooth/IBluetoothAvrcpController.aidl
index f917a50..f1288d0 100644
--- a/core/java/android/bluetooth/IBluetoothAvrcpController.aidl
+++ b/core/java/android/bluetooth/IBluetoothAvrcpController.aidl
@@ -16,7 +16,10 @@
 
 package android.bluetooth;
 
+import android.bluetooth.BluetoothAvrcpPlayerSettings;
 import android.bluetooth.BluetoothDevice;
+import android.media.MediaMetadata;
+import android.media.session.PlaybackState;
 
 /**
  * APIs for Bluetooth AVRCP controller service
@@ -28,4 +31,9 @@
     List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
     int getConnectionState(in BluetoothDevice device);
     void sendPassThroughCmd(in BluetoothDevice device, int keyCode, int keyState);
+    BluetoothAvrcpPlayerSettings getPlayerSettings(in BluetoothDevice device);
+    MediaMetadata getMetadata(in BluetoothDevice device);
+    PlaybackState getPlaybackState(in BluetoothDevice device);
+    boolean setPlayerApplicationSetting(in BluetoothAvrcpPlayerSettings plAppSetting);
+    void sendGroupNavigationCmd(in BluetoothDevice device, int keyCode, int keyState);
 }
diff --git a/core/java/android/bluetooth/OobData.aidl b/core/java/android/bluetooth/OobData.aidl
new file mode 100644
index 0000000..d831c64
--- /dev/null
+++ b/core/java/android/bluetooth/OobData.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.bluetooth;
+
+parcelable OobData;
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
new file mode 100644
index 0000000..01f72ef
--- /dev/null
+++ b/core/java/android/bluetooth/OobData.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import android.util.Log;
+
+/**
+ * Out Of Band Data for Bluetooth device.
+ */
+public class OobData implements Parcelable {
+    private byte[] securityManagerTk;
+
+    public byte[] getSecurityManagerTk() {
+        return securityManagerTk;
+    }
+
+    public void setSecurityManagerTk(byte[] securityManagerTk) {
+        this.securityManagerTk = securityManagerTk;
+    }
+
+    public OobData() { }
+
+    private OobData(Parcel in) {
+        securityManagerTk = in.createByteArray();
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeByteArray(securityManagerTk);
+    }
+
+    public static final Parcelable.Creator<OobData> CREATOR
+            = new Parcelable.Creator<OobData>() {
+        public OobData createFromParcel(Parcel in) {
+            return new OobData(in);
+        }
+
+        public OobData[] newArray(int size) {
+            return new OobData[size];
+        }
+    };
+}
\ No newline at end of file
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/Context.java b/core/java/android/content/Context.java
index 84f6f3d..48d0196 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -329,6 +329,16 @@
     public static final int BIND_NOT_VISIBLE = 0x40000000;
 
     /**
+     * Flag for {@link #bindService}: The service being bound is an
+     * {@link android.R.attr#isolatedProcess isolated},
+     * {@link android.R.attr#externalService external} service.  This binds the service into the
+     * calling application's package, rather than the package in which the service is declared.
+     * @hide
+     */
+    @SystemApi
+    public static final int BIND_EXTERNAL_SERVICE = 0x80000000;
+
+    /**
      * Returns an AssetManager instance for the application's package.
      * <p>
      * <strong>Note:</strong> Implementations of this method should return
@@ -2550,6 +2560,7 @@
             NETWORK_STATS_SERVICE,
             //@hide: NETWORK_POLICY_SERVICE,
             WIFI_SERVICE,
+            WIFI_NAN_SERVICE,
             WIFI_PASSPOINT_SERVICE,
             WIFI_P2P_SERVICE,
             WIFI_SCANNING_SERVICE,
@@ -3012,6 +3023,17 @@
     public static final String WIFI_P2P_SERVICE = "wifip2p";
 
     /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link android.net.wifi.nan.WifiNanManager} for handling management of
+     * Wi-Fi NAN discovery and connections.
+     *
+     * @see #getSystemService
+     * @see android.net.wifi.nan.WifiNanManager
+     * @hide PROPOSED_NAN_API
+     */
+    public static final String WIFI_NAN_SERVICE = "wifinan";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a {@link
      * android.net.wifi.WifiScanner} for scanning the wifi universe
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 35cd2be..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}.
      *
@@ -2537,6 +2563,16 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON";
 
+   /**
+     * Broadcast Action:  The "Picture-in-picture (PIP) Button" was pressed.
+     * Includes a single extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
+     * caused the broadcast.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PICTURE_IN_PICTURE_BUTTON =
+            "android.intent.action.PICTURE_IN_PICTURE_BUTTON";
+
     /**
      * Broadcast Action:  The "Camera Button" was pressed.  Includes a single
      * extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
@@ -3034,6 +3070,24 @@
     public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
 
     /**
+     * Broadcast Action: Sent when media resource is granted.
+     * <p>
+     * {@link #EXTRA_PACKAGES} specifies the packages on the process holding the media resource
+     * granted.
+     * </p>
+     * <p class="note">
+     * This is a protected intent that can only be sent by the system.
+     * </p>
+     * <p class="note">
+     * This requires {@link android.Manifest.permission#RECEIVE_MEDIA_RESOURCE_USAGE} permission.
+     * </p>
+     *
+     * @hide
+     */
+    public static final String ACTION_MEDIA_RESOURCE_GRANTED =
+            "android.intent.action.MEDIA_RESOURCE_GRANTED";
+
+    /**
      * Activity Action: Allow the user to select and return one or more existing
      * documents. When invoked, the system will display the various
      * {@link DocumentsProvider} instances installed on the device, letting the
@@ -3922,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 =
@@ -4077,6 +4133,34 @@
      * Optional boolean extra indicating whether quiet mode has been switched on or off.
      */
     public static final String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
+
+    /**
+     * Used as an int extra field in {@link #ACTION_MEDIA_RESOURCE_GRANTED}
+     * intents to specify the resource type granted. Possible values are
+     * {@link #EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC} or
+     * {@link #EXTRA_MEDIA_RESOURCE_TYPE_AUDIO_CODEC}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_MEDIA_RESOURCE_TYPE =
+            "android.intent.extra.MEDIA_RESOURCE_TYPE";
+
+    /**
+     * Used as an int value for {@link #EXTRA_MEDIA_RESOURCE_TYPE}
+     * to represent that a video codec is allowed to use.
+     *
+     * @hide
+     */
+    public static final int EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC = 0;
+
+    /**
+     * Used as an int value for {@link #EXTRA_MEDIA_RESOURCE_TYPE}
+     * to represent that a audio codec is allowed to use.
+     *
+     * @hide
+     */
+    public static final int EXTRA_MEDIA_RESOURCE_TYPE_AUDIO_CODEC = 1;
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
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 f611991..2c6b604 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -294,6 +294,8 @@
     void restoreDefaultApps(in byte[] backup, int userId);
     byte[] getIntentFilterVerificationBackup(int userId);
     void restoreIntentFilterVerification(in byte[] backup, int userId);
+    byte[] getPermissionGrantBackup(int userId);
+    void restorePermissionGrants(in byte[] backup, int userId);
 
     /**
      * Report the set of 'Home' activity candidates, plus (if any) which of them
@@ -427,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/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5113e19..ba4d14c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1902,6 +1902,16 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports Wi-Fi Aware (NAN)
+     * networking.
+     *
+     * @hide PROPOSED_NAN_API
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_WIFI_NAN = "android.hardware.wifi.nan";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: This is a device dedicated to showing UI
      * on a vehicle headunit. A headunit here is defined to be inside a
      * vehicle that may or may not be moving. A headunit uses either a
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a0df610..a6fec9f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -51,6 +51,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.TypedValue;
+import android.util.apk.ApkSignatureSchemeV2Verifier;
 import android.util.jar.StrictJarFile;
 import android.view.Gravity;
 
@@ -1022,11 +1023,56 @@
         final boolean requireCode = ((parseFlags & PARSE_ENFORCE_CODE) != 0) && hasCode;
         final String apkPath = apkFile.getAbsolutePath();
 
+        // Try to verify the APK using APK Signature Scheme v2.
+        boolean verified = false;
+        {
+            Certificate[][] allSignersCerts = null;
+            Signature[] signatures = null;
+            try {
+                allSignersCerts = ApkSignatureSchemeV2Verifier.verify(apkPath);
+                signatures = convertToSignatures(allSignersCerts);
+                // APK verified using APK Signature Scheme v2.
+                verified = true;
+            } catch (ApkSignatureSchemeV2Verifier.SignatureNotFoundException e) {
+                // No APK Signature Scheme v2 signature found
+            } catch (Exception e) {
+                // APK Signature Scheme v2 signature was found but did not verify
+                throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+                        "Failed to collect certificates from " + apkPath
+                                + " using APK Signature Scheme v2",
+                        e);
+            }
+
+            if (verified) {
+                if (pkg.mCertificates == null) {
+                    pkg.mCertificates = allSignersCerts;
+                    pkg.mSignatures = signatures;
+                    pkg.mSigningKeys = new ArraySet<>(allSignersCerts.length);
+                    for (int i = 0; i < allSignersCerts.length; i++) {
+                        Certificate[] signerCerts = allSignersCerts[i];
+                        Certificate signerCert = signerCerts[0];
+                        pkg.mSigningKeys.add(signerCert.getPublicKey());
+                    }
+                } else {
+                    if (!Signature.areExactMatch(pkg.mSignatures, signatures)) {
+                        throw new PackageParserException(
+                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+                                apkPath + " has mismatched certificates");
+                    }
+                }
+                // Not yet done, because we need to confirm that AndroidManifest.xml exists and,
+                // if requested, that classes.dex exists.
+            }
+        }
+
         boolean codeFound = false;
         StrictJarFile jarFile = null;
         try {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
-            jarFile = new StrictJarFile(apkPath);
+            jarFile = new StrictJarFile(
+                    apkPath,
+                    !verified // whether to verify JAR signature
+                    );
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
             // Always verify manifest, regardless of source
@@ -1036,6 +1082,16 @@
                         "Package " + apkPath + " has no manifest");
             }
 
+            // Optimization: early termination when APK already verified
+            if (verified) {
+                if ((requireCode) && (jarFile.findEntry(BYTECODE_FILENAME) == null)) {
+                    throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+                            "Package " + apkPath + " code is missing");
+                }
+                return;
+            }
+
+            // APK's integrity needs to be verified using JAR signature scheme.
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "buildVerifyList");
             final List<ZipEntry> toVerify = new ArrayList<>();
             toVerify.add(manifestEntry);
@@ -3886,6 +3942,11 @@
             s.info.flags |= ServiceInfo.FLAG_ISOLATED_PROCESS;
         }
         if (sa.getBoolean(
+                com.android.internal.R.styleable.AndroidManifestService_externalService,
+                false)) {
+            s.info.flags |= ServiceInfo.FLAG_EXTERNAL_SERVICE;
+        }
+        if (sa.getBoolean(
                 com.android.internal.R.styleable.AndroidManifestService_singleUser,
                 false)) {
             s.info.flags |= ServiceInfo.FLAG_SINGLE_USER;
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 74e5c2a..eecf0de 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -49,6 +49,14 @@
     public static final int FLAG_ISOLATED_PROCESS = 0x0002;
 
     /**
+     * Bit in {@link #flags}: If set, the service can be bound and run in the
+     * calling application's package, rather than the package in which it is
+     * declared.  Set from {@link android.R.attr#externalService} attribute.
+     * @hide
+     */
+    public static final int FLAG_EXTERNAL_SERVICE = 0x0004;
+
+    /**
      * Bit in {@link #flags}: If set, a single instance of the service will
      * run for all users on the device.  Set from the
      * {@link android.R.attr#singleUser} attribute.
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index e3050fe..9cf4675 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -145,6 +145,10 @@
         return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL;
     }
 
+    public boolean isInitialized() {
+        return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED;
+    }
+
     /**
      * Returns true if the user is a split system user.
      * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
diff --git a/core/java/android/content/res/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/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index e875864..6935174 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -534,6 +534,24 @@
     public static final String STRING_TYPE_WRIST_TILT_GESTURE = "android.sensor.wrist_tilt_gesture";
 
     /**
+     * The current orientation of the device.
+     * <p>
+     * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+     *
+     * @hide Expected to be used internally for auto-rotate and speaker rotation.
+     *
+     */
+    public static final int TYPE_DEVICE_ORIENTATION = 27;
+
+    /**
+     * A constant string describing a device orientation sensor type.
+     *
+     * @hide
+     * @see #TYPE_DEVICE_ORIENTATION
+     */
+    public static final String STRING_TYPE_DEVICE_ORIENTATION = "android.sensor.device_orientation";
+
+    /**
      * A constant describing all sensor types.
      */
     public static final int TYPE_ALL = -1;
@@ -618,6 +636,7 @@
             1, // SENSOR_TYPE_GLANCE_GESTURE
             1, // SENSOR_TYPE_PICK_UP_GESTURE
             1, // SENSOR_TYPE_WRIST_TILT_GESTURE
+            1, // SENSOR_TYPE_DEVICE_ORIENTATION
     };
 
     /**
@@ -939,6 +958,9 @@
             case TYPE_TEMPERATURE:
                 mStringType = STRING_TYPE_TEMPERATURE;
                 return true;
+            case TYPE_DEVICE_ORIENTATION:
+                mStringType = STRING_TYPE_DEVICE_ORIENTATION;
+                return true;
             default:
                 return false;
         }
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 906c2a19..9937b2c 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -483,6 +483,20 @@
      * on it. In earlier versions, this used to be always 3 which has changed now. </p>
      *
      * @see GeomagneticField
+     *
+     * <h4> {@link android.hardware.Sensor#TYPE_DEVICE_ORIENTATION
+     * Sensor.TYPE_DEVICE_ORIENTATION}:</h4>
+     * The current device orientation will be available in values[0]. The only
+     * available values are:
+     * <ul>
+     * <li> 0: device is in default orientation (Y axis is vertical and points up)
+     * <li> 1: device is rotated 90 degrees counter-clockwise from default
+     *         orientation (X axis is vertical and points up)
+     * <li> 2: device is rotated 180 degrees from default orientation (Y axis is
+     *         vertical and points down)
+     * <li> 3: device is rotated 90 degrees clockwise from default orientation (X axis
+     *         is vertical and points down)
+     * </ul>
      */
     public final float[] values;
 
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 6e02df1..c3a4954 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -89,7 +89,6 @@
             new SparseArray<CaptureCallbackHolder>();
 
     private int mRepeatingRequestId = REQUEST_ID_NONE;
-    private final ArrayList<Integer> mRepeatingRequestIdDeletedList = new ArrayList<Integer>();
     // Map stream IDs to input/output configurations
     private SimpleEntry<Integer, InputConfiguration> mConfiguredInput =
             new SimpleEntry<>(REQUEST_ID_NONE, null);
@@ -916,11 +915,6 @@
                 int requestId = mRepeatingRequestId;
                 mRepeatingRequestId = REQUEST_ID_NONE;
 
-                // Queue for deletion after in-flight requests finish
-                if (mCaptureCallbackMap.get(requestId) != null) {
-                    mRepeatingRequestIdDeletedList.add(requestId);
-                }
-
                 try {
                     LongParcelable lastFrameNumberRef = new LongParcelable();
                     mRemoteDevice.cancelRequest(requestId, /*out*/lastFrameNumberRef);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 176e923..c4f0847 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -17,6 +17,7 @@
 
 import static com.android.internal.util.Preconditions.checkNotNull;
 
+import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -686,6 +687,47 @@
     }
 
     /**
+     * Configures an always-on VPN connection through a specific application.
+     * This connection is automatically granted and persisted after a reboot.
+     *
+     * <p>The designated package should declare a {@link VpnService} in its
+     *    manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
+     *    otherwise the call will fail.
+     *
+     * @param userId The identifier of the user to set an always-on VPN for.
+     * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
+     *                   to remove an existing always-on VPN configuration.
+
+     * @return {@code true} if the package is set as always-on VPN controller;
+     *         {@code false} otherwise.
+     * @hide
+     */
+    public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage) {
+        try {
+            return mService.setAlwaysOnVpnPackage(userId, vpnPackage);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the package name of the currently set always-on VPN application.
+     * If there is no always-on VPN set, or the VPN is provided by the system instead
+     * of by an app, {@code null} will be returned.
+     *
+     * @return Package name of VPN controller responsible for always-on VPN,
+     *         or {@code null} if none is set.
+     * @hide
+     */
+    public String getAlwaysOnVpnPackageForUser(int userId) {
+        try {
+            return mService.getAlwaysOnVpnPackage(userId);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Returns details about the currently active default data network
      * for a given uid.  This is for internal use only to avoid spying
      * other apps.
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index ef91137..569468e 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -117,6 +117,8 @@
     VpnInfo[] getAllVpnInfo();
 
     boolean updateLockdownVpn();
+    boolean setAlwaysOnVpnPackage(int userId, String packageName);
+    String getAlwaysOnVpnPackage(int userId);
 
     int checkMobileProvisioning(int suggestedTimeOutMs);
 
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/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 3ac1dcc..26d2bec 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -25,13 +25,13 @@
  */
 interface INfcTag
 {
-    int close(int nativeHandle);
     int connect(int nativeHandle, int technology);
     int reconnect(int nativeHandle);
     int[] getTechList(int nativeHandle);
     boolean isNdef(int nativeHandle);
     boolean isPresent(int nativeHandle);
     TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
+    boolean done(int nativeHandle, int debounceMs);
 
     NdefMessage ndefRead(int nativeHandle);
     int ndefWrite(int nativeHandle, in NdefMessage msg);
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 154d5a1..40d5a8db 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -214,6 +214,42 @@
         return techIntList;
     }
 
+    /**
+     * Signals that you are no longer interested in communicating with this tag
+     * for as long as it remains in range.
+     *
+     * All future attempted communication to this tag will fail with {@link IOException}.
+     * The NFC controller will be put in a low-power polling mode, allowing the device
+     * to save power in cases where it's "attached" to a tag all the time (eg a tag in
+     * car dock).
+     *
+     * Additionally the debounceMs parameter allows you to specify for how long the tag needs
+     * to have gone out of range, before it will be dispatched again.
+     *
+     * Note: the NFC controller typically polls at a pretty slow interval (100 - 500 ms).
+     * This means that if the tag repeatedly goes in and out of range (for example, in
+     * case of a flaky connection), and the controller happens to poll every time the
+     * tag is out of range, it *will* re-dispatch the tag after debounceMs, despite the tag
+     * having been "in range" during the interval.
+     *
+     * Note 2: if a tag with another UID is detected after this API is called, its effect
+     * will be cancelled; if this tag shows up before the amount of time specified in
+     * debounceMs, it will be dispatched again.
+     *
+     * Note 3: some tags have a random UID, in which case this API won't work.
+     *
+     * @param debounceMs minimum amount of time the tag needs to be out of range before being
+     *                   dispatched again.
+     * @return false if the Tag couldn't be found (or has gone out of range), true otherwise
+     */
+    public boolean done(int debounceMs) {
+        try {
+            return mTagService.done(getServiceHandle(), debounceMs);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     private static HashMap<String, Integer> getTechStringToCodeMap() {
         HashMap<String, Integer> techStringToCodeMap = new HashMap<String, Integer>();
 
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/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index 7a1a6a2..838279b 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.os.IMaintenanceActivityListener;
 import android.os.UserHandle;
 
 /** @hide */
@@ -37,4 +38,6 @@
     void exitIdle(String reason);
     void downloadServiceActive(IBinder token);
     void downloadServiceInactive();
+    boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener);
+    void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener);
 }
diff --git a/core/java/android/os/IMaintenanceActivityListener.aidl b/core/java/android/os/IMaintenanceActivityListener.aidl
new file mode 100644
index 0000000..6a2581f
--- /dev/null
+++ b/core/java/android/os/IMaintenanceActivityListener.aidl
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/** @hide */
+oneway interface IMaintenanceActivityListener {
+    void onMaintenanceActivityChanged(boolean active);
+}
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 9ee6228..bc2566b 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -18,6 +18,7 @@
 package android.os;
 
 import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.content.pm.UserInfo;
 import android.content.RestrictionEntry;
 import android.graphics.Bitmap;
@@ -35,7 +36,7 @@
 
     UserInfo createUser(in String name, int flags);
     UserInfo createProfileForUser(in String name, int flags, int userHandle);
-    UserInfo createRestrictedProfile(String name, int parentUserId);
+    UserInfo createRestrictedProfile(String name, int parentUserHandle);
     void setUserEnabled(int userHandle);
     boolean removeUser(int userHandle);
     void setUserName(int userHandle, String name);
@@ -44,21 +45,21 @@
     UserInfo getPrimaryUser();
     List<UserInfo> getUsers(boolean excludeDying);
     List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
-    boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne);
+    boolean canAddMoreManagedProfiles(int userHandle, boolean allowedToRemoveOne);
     UserInfo getProfileParent(int userHandle);
-    boolean isSameProfileGroup(int userId, int otherUserId);
+    boolean isSameProfileGroup(int userHandle, int otherUserHandle);
     UserInfo getUserInfo(int userHandle);
-    String getUserAccount(int userId);
-    void setUserAccount(int userId, String accountName);
+    String getUserAccount(int userHandle);
+    void setUserAccount(int userHandle, String accountName);
     long getUserCreationTime(int userHandle);
     boolean isRestricted();
-    boolean canHaveRestrictedProfile(int userId);
+    boolean canHaveRestrictedProfile(int userHandle);
     int getUserSerialNumber(int userHandle);
     int getUserHandle(int userSerialNumber);
     Bundle getUserRestrictions(int userHandle);
     boolean hasBaseUserRestriction(String restrictionKey, int userHandle);
     boolean hasUserRestriction(in String restrictionKey, int userHandle);
-    void setUserRestriction(String key, boolean value, int userId);
+    void setUserRestriction(String key, boolean value, int userHandle);
     void setApplicationRestrictions(in String packageName, in Bundle restrictions,
             int userHandle);
     Bundle getApplicationRestrictions(in String packageName);
@@ -68,4 +69,11 @@
     boolean markGuestForDeletion(int userHandle);
     void setQuietModeEnabled(int userHandle, boolean enableQuietMode);
     boolean isQuietModeEnabled(int userHandle);
+    void setSeedAccountData(int userHandle, in String accountName,
+            in String accountType, in PersistableBundle accountOptions, boolean persist);
+    String getSeedAccountName();
+    String getSeedAccountType();
+    PersistableBundle getSeedAccountOptions();
+    void clearSeedAccountData();
+    boolean someUserHasSeedAccount(in String accountName, in String accountType);
 }
diff --git a/core/java/android/os/PersistableBundle.aidl b/core/java/android/os/PersistableBundle.aidl
deleted file mode 100644
index 94e8607..0000000
--- a/core/java/android/os/PersistableBundle.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-**
-** Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.os;
-
-parcelable PersistableBundle cpp_header "binder/PersistableBundle.h";
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index d1b3f59..f01f597 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -26,6 +26,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -567,6 +568,37 @@
      */
     public static final String KEY_RESTRICTIONS_PENDING = "restrictions_pending";
 
+    private static final String ACTION_CREATE_USER = "android.os.action.CREATE_USER";
+
+    /**
+     * Extra containing a name for the user being created. Optional parameter passed to
+     * ACTION_CREATE_USER activity.
+     * @hide
+     */
+    public static final String EXTRA_USER_NAME = "android.os.extra.USER_NAME";
+
+    /**
+     * Extra containing account name for the user being created. Optional parameter passed to
+     * ACTION_CREATE_USER activity.
+     * @hide
+     */
+    public static final String EXTRA_USER_ACCOUNT_NAME = "android.os.extra.USER_ACCOUNT_NAME";
+
+    /**
+     * Extra containing account type for the user being created. Optional parameter passed to
+     * ACTION_CREATE_USER activity.
+     * @hide
+     */
+    public static final String EXTRA_USER_ACCOUNT_TYPE = "android.os.extra.USER_ACCOUNT_TYPE";
+
+    /**
+     * Extra containing account-specific data for the user being created. Optional parameter passed
+     * to ACTION_CREATE_USER activity.
+     * @hide
+     */
+    public static final String EXTRA_USER_ACCOUNT_OPTIONS
+            = "android.os.extra.USER_ACCOUNT_OPTIONS";
+
     /** @hide */
     public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3;
     /** @hide */
@@ -766,9 +798,13 @@
      * @param user The user to retrieve the running state for.
      */
     public boolean isUserRunning(UserHandle user) {
+        return isUserRunning(user.getIdentifier());
+    }
+
+    /** {@hide} */
+    public boolean isUserRunning(int userId) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(
-                    user.getIdentifier(), 0);
+            return ActivityManagerNative.getDefault().isUserRunning(userId, 0);
         } catch (RemoteException e) {
             return false;
         }
@@ -1138,6 +1174,137 @@
     }
 
     /**
+     * Returns an intent to create a user for the provided name and email address. The name
+     * and email address will be used when the setup process for the new user is started.
+     * If this device does not support multiple users, null is returned.
+     * <p/>
+     * The intent should be launched using startActivityForResult and the return result will
+     * indicate if the user consented to adding a new user and if the operation succeeded.
+     * <p/>
+     * The new user is created but not initialized. After switching into the user for the first
+     * time, the preferred user name and account information are used by the setup process for that
+     * user.
+     *
+     * @param userName Optional name to assign to the user.
+     * @param accountName Optional email address that will be used by the setup wizard to initialize
+     *                    the user.
+     * @param accountType Optional account type for the account to be created. This is required
+     *                    if the account name is specified.
+     * @param accountOptions Optional bundle of data to be passed in during account creation in the
+     *                       new user via {@link AccountManager#addAccount(String, String, String[],
+     *                       Bundle, android.app.Activity, android.accounts.AccountManagerCallback,
+     *                       Handler)}.
+     * @return An Intent that can be launched from an Activity or null if creating users is not
+     *         supported on this device.
+     */
+    public static Intent createUserCreationIntent(@Nullable String userName,
+            @Nullable String accountName,
+            @Nullable String accountType, @Nullable PersistableBundle accountOptions) {
+        if (!supportsMultipleUsers() || getMaxSupportedUsers() < 2) {
+            return null;
+        }
+        Intent intent = new Intent(ACTION_CREATE_USER);
+        if (userName != null) {
+            intent.putExtra(EXTRA_USER_NAME, userName);
+        }
+        if (accountName != null && accountType == null) {
+            throw new IllegalArgumentException("accountType must be specified if accountName is "
+                    + "specified");
+        }
+        if (accountName != null) {
+            intent.putExtra(EXTRA_USER_ACCOUNT_NAME, accountName);
+        }
+        if (accountType != null) {
+            intent.putExtra(EXTRA_USER_ACCOUNT_TYPE, accountType);
+        }
+        if (accountOptions != null) {
+            intent.putExtra(EXTRA_USER_ACCOUNT_OPTIONS, accountOptions);
+        }
+        return intent;
+    }
+
+    /**
+     * @hide
+     *
+     * Returns the preferred account name for user creation. Requires MANAGE_USERS permission.
+     */
+    @SystemApi
+    public String getSeedAccountName() {
+        try {
+            return mService.getSeedAccountName();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not get the seed account name", re);
+            return null;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Returns the preferred account type for user creation. Requires MANAGE_USERS permission.
+     */
+    @SystemApi
+    public String getSeedAccountType() {
+        try {
+            return mService.getSeedAccountType();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not get the seed account type", re);
+            return null;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Returns the preferred account's options bundle for user creation. Requires MANAGE_USERS
+     * permission.
+     * @return Any options set by the requestor that created the user.
+     */
+    @SystemApi
+    public PersistableBundle getSeedAccountOptions() {
+        try {
+            return mService.getSeedAccountOptions();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not get the seed account options", re);
+            return null;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Called by a system activity to set the seed account information of a user created
+     * through the user creation intent.
+     * @param userId
+     * @param accountName
+     * @param accountType
+     * @param accountOptions
+     * @see #createUserCreationIntent(String, String, String, PersistableBundle)
+     */
+    public void setSeedAccountData(int userId, String accountName, String accountType,
+            PersistableBundle accountOptions) {
+        try {
+            mService.setSeedAccountData(userId, accountName, accountType, accountOptions,
+                    /* persist= */ true);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not set the seed account data", re);
+        }
+    }
+
+    /**
+     * @hide
+     * Clears the seed information used to create this user. Requires MANAGE_USERS permission.
+     */
+    @SystemApi
+    public void clearSeedAccountData() {
+        try {
+            mService.clearSeedAccountData();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not clear the seed account data", re);
+        }
+    }
+
+    /**
      * @hide
      * Marks the guest user for deletion to allow a new guest to be created before deleting
      * the current user who is a guest.
@@ -1752,4 +1919,21 @@
             return 0;
         }
     }
+
+    /**
+     * @hide
+     * Checks if any uninitialized user has the specific seed account name and type.
+     *
+     * @param mAccountName The account name to check for
+     * @param mAccountType The account type of the account to check for
+     * @return whether the seed account was found
+     */
+    public boolean someUserHasSeedAccount(String accountName, String accountType) {
+        try {
+            return mService.someUserHasSeedAccount(accountName, accountType);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not check seed accounts", re);
+            return false;
+        }
+    }
 }
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/print/PrinterId.java b/core/java/android/print/PrinterId.java
index 83efe80..ff9c0df 100644
--- a/core/java/android/print/PrinterId.java
+++ b/core/java/android/print/PrinterId.java
@@ -20,16 +20,17 @@
 import android.content.ComponentName;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
 
 /**
  * This class represents the unique id of a printer.
  */
 public final class PrinterId implements Parcelable {
 
-    private final ComponentName mServiceName;
+    private final @NonNull ComponentName mServiceName;
 
-    private final String mLocalId;
+    private final @NonNull String mLocalId;
 
     /**
      * Creates a new instance.
@@ -39,14 +40,14 @@
      *
      * @hide
      */
-    public PrinterId(ComponentName serviceName, String localId) {
+    public PrinterId(@NonNull ComponentName serviceName, @NonNull String localId) {
         mServiceName = serviceName;
         mLocalId = localId;
     }
 
-    private PrinterId(Parcel parcel) {
-        mServiceName = parcel.readParcelable(null);
-        mLocalId = parcel.readString();
+    private PrinterId(@NonNull Parcel parcel) {
+        mServiceName = Preconditions.checkNotNull((ComponentName) parcel.readParcelable(null));
+        mLocalId = Preconditions.checkNotNull(parcel.readString());
     }
 
     /**
@@ -56,7 +57,7 @@
      *
      * @hide
      */
-    public ComponentName getServiceName() {
+    public @NonNull ComponentName getServiceName() {
         return mServiceName;
     }
 
@@ -93,14 +94,10 @@
             return false;
         }
         PrinterId other = (PrinterId) object;
-        if (mServiceName == null) {
-            if (other.mServiceName != null) {
-                return false;
-            }
-        } else if (!mServiceName.equals(other.mServiceName)) {
+        if (!mServiceName.equals(other.mServiceName)) {
             return false;
         }
-        if (!TextUtils.equals(mLocalId, other.mLocalId)) {
+        if (!mLocalId.equals(other.mLocalId)) {
             return false;
         }
         return true;
@@ -110,8 +107,7 @@
     public int hashCode() {
         final int prime = 31;
         int hashCode = 1;
-        hashCode = prime * hashCode + ((mServiceName != null)
-                ? mServiceName.hashCode() : 1);
+        hashCode = prime * hashCode + mServiceName.hashCode();
         hashCode = prime * hashCode + mLocalId.hashCode();
         return hashCode;
     }
diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java
index afef9c0..0d2d9f4 100644
--- a/core/java/android/print/PrinterInfo.java
+++ b/core/java/android/print/PrinterInfo.java
@@ -33,6 +33,8 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import com.android.internal.util.Preconditions;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -43,6 +45,9 @@
  * major components, printer properties such as name, id, status,
  * description and printer capabilities which describe the various
  * print modes a printer supports such as media sizes, margins, etc.
+ * <p>
+ * Once {@link PrinterInfo.Builder#build() built} the objects are immutable.
+ * </p>
  */
 public final class PrinterInfo implements Parcelable {
 
@@ -62,60 +67,41 @@
     /** Printer status: the printer is not available. */
     public static final int STATUS_UNAVAILABLE = 3;
 
-    private PrinterId mId;
+    private final @NonNull PrinterId mId;
 
     /** Resource inside the printer's services's package to be used as an icon */
-    private int mIconResourceId;
+    private final int mIconResourceId;
 
     /** If a custom icon can be loaded for the printer */
-    private boolean mHasCustomPrinterIcon;
+    private final boolean mHasCustomPrinterIcon;
 
     /** The generation of the icon in the cache. */
-    private int mCustomPrinterIconGen;
+    private final int mCustomPrinterIconGen;
 
     /** Intent that launches the activity showing more information about the printer. */
-    private PendingIntent mInfoIntent;
+    private final @Nullable PendingIntent mInfoIntent;
 
-    private String mName;
+    private final @NonNull String mName;
 
-    private int mStatus;
+    private final @Status int mStatus;
 
-    private String mDescription;
+    private final @Nullable String mDescription;
 
-    private PrinterCapabilitiesInfo mCapabilities;
+    private final @Nullable PrinterCapabilitiesInfo mCapabilities;
 
-    private PrinterInfo() {
-        /* do nothing */
-    }
-
-    private PrinterInfo(PrinterInfo prototype) {
-        copyFrom(prototype);
-    }
-
-    /**
-     * @hide
-     */
-    public void copyFrom(PrinterInfo other) {
-        if (this == other) {
-            return;
-        }
-        mId = other.mId;
-        mName = other.mName;
-        mStatus = other.mStatus;
-        mDescription = other.mDescription;
-        if (other.mCapabilities != null) {
-            if (mCapabilities != null) {
-                mCapabilities.copyFrom(other.mCapabilities);
-            } else {
-                mCapabilities = new PrinterCapabilitiesInfo(other.mCapabilities);
-            }
-        } else {
-            mCapabilities = null;
-        }
-        mIconResourceId = other.mIconResourceId;
-        mHasCustomPrinterIcon = other.mHasCustomPrinterIcon;
-        mCustomPrinterIconGen = other.mCustomPrinterIconGen;
-        mInfoIntent = other.mInfoIntent;
+    private PrinterInfo(@NonNull PrinterId printerId, @NonNull String name, @Status int status,
+            int iconResourceId, boolean hasCustomPrinterIcon, String description,
+            PendingIntent infoIntent, PrinterCapabilitiesInfo capabilities,
+            int customPrinterIconGen) {
+        mId = printerId;
+        mName = name;
+        mStatus = status;
+        mIconResourceId = iconResourceId;
+        mHasCustomPrinterIcon = hasCustomPrinterIcon;
+        mDescription = description;
+        mInfoIntent = infoIntent;
+        mCapabilities = capabilities;
+        mCustomPrinterIconGen = customPrinterIconGen;
     }
 
     /**
@@ -180,7 +166,7 @@
      *
      * @return The printer name.
      */
-    public @Nullable String getName() {
+    public @NonNull String getName() {
         return mName;
     }
 
@@ -227,10 +213,51 @@
         return mCapabilities;
     }
 
+    /**
+     * Check if printerId is valid.
+     *
+     * @param printerId The printerId that might be valid
+     * @return The valid printerId
+     * @throws IllegalArgumentException if printerId is not valid.
+     */
+    private static @NonNull PrinterId checkPrinterId(PrinterId printerId) {
+        return Preconditions.checkNotNull(printerId, "printerId cannot be null.");
+    }
+
+    /**
+     * Check if status is valid.
+     *
+     * @param status The status that might be valid
+     * @return The valid status
+     * @throws IllegalArgumentException if status is not valid.
+     */
+    private static @Status int checkStatus(int status) {
+        if (!(status == STATUS_IDLE
+                || status == STATUS_BUSY
+                || status == STATUS_UNAVAILABLE)) {
+            throw new IllegalArgumentException("status is invalid.");
+        }
+
+        return status;
+    }
+
+    /**
+     * Check if name is valid.
+     *
+     * @param name The name that might be valid
+     * @return The valid name
+     * @throws IllegalArgumentException if name is not valid.
+     */
+    private static @NonNull String checkName(String name) {
+        return Preconditions.checkStringNotEmpty(name, "name cannot be empty.");
+    }
+
     private PrinterInfo(Parcel parcel) {
-        mId = parcel.readParcelable(null);
-        mName = parcel.readString();
-        mStatus = parcel.readInt();
+        // mName can be null due to unchecked set in Builder.setName and status can be invalid
+        // due to unchecked set in Builder.setStatus, hence we can only check mId for a valid state
+        mId = checkPrinterId((PrinterId) parcel.readParcelable(null));
+        mName = checkName(parcel.readString());
+        mStatus = checkStatus(parcel.readInt());
         mDescription = parcel.readString();
         mCapabilities = parcel.readParcelable(null);
         mIconResourceId = parcel.readInt();
@@ -261,8 +288,8 @@
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + ((mId != null) ? mId.hashCode() : 0);
-        result = prime * result + ((mName != null) ? mName.hashCode() : 0);
+        result = prime * result + mId.hashCode();
+        result = prime * result + mName.hashCode();
         result = prime * result + mStatus;
         result = prime * result + ((mDescription != null) ? mDescription.hashCode() : 0);
         result = prime * result + ((mCapabilities != null) ? mCapabilities.hashCode() : 0);
@@ -282,15 +309,11 @@
      * @hide
      */
     public boolean equalsIgnoringStatus(PrinterInfo other) {
-        if (mId == null) {
-            if (other.mId != null) {
-                return false;
-            }
-        } else if (!mId.equals(other.mId)) {
+        if (!mId.equals(other.mId)) {
             return false;
         }
-        if (!TextUtils.equals(mName, other.mName)) {
-            return false;
+        if (!mName.equals(other.mName)) {
+           return false;
         }
         if (!TextUtils.equals(mDescription, other.mDescription)) {
             return false;
@@ -363,7 +386,15 @@
      * Builder for creating of a {@link PrinterInfo}.
      */
     public static final class Builder {
-        private final PrinterInfo mPrototype;
+        private @NonNull PrinterId mPrinterId;
+        private @NonNull String mName;
+        private @Status int mStatus;
+        private int mIconResourceId;
+        private boolean mHasCustomPrinterIcon;
+        private String mDescription;
+        private PendingIntent mInfoIntent;
+        private PrinterCapabilitiesInfo mCapabilities;
+        private int mCustomPrinterIconGen;
 
         /**
          * Constructor.
@@ -375,19 +406,9 @@
          * printer name is empty or the status is not a valid one.
          */
         public Builder(@NonNull PrinterId printerId, @NonNull String name, @Status int status) {
-            if (printerId == null) {
-                throw new IllegalArgumentException("printerId cannot be null.");
-            }
-            if (TextUtils.isEmpty(name)) {
-                throw new IllegalArgumentException("name cannot be empty.");
-            }
-            if (!isValidStatus(status)) {
-                throw new IllegalArgumentException("status is invalid.");
-            }
-            mPrototype = new PrinterInfo();
-            mPrototype.mId = printerId;
-            mPrototype.mName = name;
-            mPrototype.mStatus = status;
+            mPrinterId = checkPrinterId(printerId);
+            mName = checkName(name);
+            mStatus = checkStatus(status);
         }
 
         /**
@@ -396,8 +417,15 @@
          * @param other Other info from which to start building.
          */
         public Builder(@NonNull PrinterInfo other) {
-            mPrototype = new PrinterInfo();
-            mPrototype.copyFrom(other);
+            mPrinterId = other.mId;
+            mName = other.mName;
+            mStatus = other.mStatus;
+            mIconResourceId = other.mIconResourceId;
+            mHasCustomPrinterIcon = other.mHasCustomPrinterIcon;
+            mDescription = other.mDescription;
+            mInfoIntent = other.mInfoIntent;
+            mCapabilities = other.mCapabilities;
+            mCustomPrinterIconGen = other.mCustomPrinterIconGen;
         }
 
         /**
@@ -405,13 +433,12 @@
          *
          * @param status The status.
          * @return This builder.
-         *
          * @see PrinterInfo#STATUS_IDLE
          * @see PrinterInfo#STATUS_BUSY
          * @see PrinterInfo#STATUS_UNAVAILABLE
          */
         public @NonNull Builder setStatus(@Status int status) {
-            mPrototype.mStatus = status;
+            mStatus = checkStatus(status);
             return this;
         }
 
@@ -424,7 +451,8 @@
          * @see PrinterInfo.Builder#setHasCustomPrinterIcon
          */
         public @NonNull Builder setIconResourceId(@DrawableRes int iconResourceId) {
-            mPrototype.mIconResourceId = iconResourceId;
+            mIconResourceId = Preconditions.checkArgumentNonnegative(iconResourceId,
+                    "iconResourceId can't be negative");
             return this;
         }
 
@@ -442,7 +470,7 @@
          * @return This builder.
          */
         public @NonNull Builder setHasCustomPrinterIcon() {
-            mPrototype.mHasCustomPrinterIcon = true;
+            mHasCustomPrinterIcon = true;
             return this;
         }
 
@@ -454,7 +482,7 @@
          * @return This builder.
          */
         public @NonNull Builder setName(@NonNull String name) {
-            mPrototype.mName = name;
+            mName = checkName(name);
             return this;
         }
 
@@ -466,7 +494,7 @@
          * @return This builder.
          */
         public @NonNull Builder setDescription(@NonNull String description) {
-            mPrototype.mDescription = description;
+            mDescription = description;
             return this;
         }
 
@@ -478,7 +506,7 @@
          * @return This builder.
          */
         public @NonNull Builder setInfoIntent(@NonNull PendingIntent infoIntent) {
-            mPrototype.mInfoIntent = infoIntent;
+            mInfoIntent = infoIntent;
             return this;
         }
 
@@ -489,7 +517,7 @@
          * @return This builder.
          */
         public @NonNull Builder setCapabilities(@NonNull PrinterCapabilitiesInfo capabilities) {
-            mPrototype.mCapabilities = capabilities;
+            mCapabilities = capabilities;
             return this;
         }
 
@@ -499,13 +527,9 @@
          * @return A new {@link PrinterInfo}.
          */
         public @NonNull PrinterInfo build() {
-            return mPrototype;
-        }
-
-        private boolean isValidStatus(int status) {
-            return (status == STATUS_IDLE
-                    || status == STATUS_BUSY
-                    || status == STATUS_UNAVAILABLE);
+            return new PrinterInfo(mPrinterId, mName, mStatus, mIconResourceId,
+                    mHasCustomPrinterIcon, mDescription, mInfoIntent, mCapabilities,
+                    mCustomPrinterIconGen);
         }
 
         /**
@@ -517,7 +541,7 @@
          * @hide
          */
         public @NonNull Builder incCustomPrinterIconGen() {
-            mPrototype.mCustomPrinterIconGen++;
+            mCustomPrinterIconGen++;
             return this;
         }
     }
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/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index d0037b7..3104492 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -30,6 +30,8 @@
 import android.print.PrinterId;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -346,6 +348,7 @@
      */
     public final PrinterId generatePrinterId(String localId) {
         throwIfNotCalledOnMainThread();
+        localId = Preconditions.checkNotNull(localId, "localId cannot be null");
         return new PrinterId(new ComponentName(getPackageName(),
                 getClass().getName()), localId);
     }
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
new file mode 100644
index 0000000..2a9d4ae
--- /dev/null
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -0,0 +1,128 @@
+/*
+ * 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.provider;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * Constants and methods to access blocked phone numbers for incoming calls and texts.
+ *
+ * TODO javadoc
+ * - Proper javadoc tagging.
+ * - Code sample?
+ * - Describe who can access it.
+ */
+public class BlockedNumberContract {
+    private BlockedNumberContract() {
+    }
+
+    /** The authority for the contacts provider */
+    public static final String AUTHORITY = "com.android.blockednumber";
+
+    /** A content:// style uri to the authority for the contacts provider */
+    public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
+
+    /**
+     * TODO javadoc
+     *
+     * Constants to interact with the blocked phone number list.
+     */
+    public static class BlockedNumbers {
+        private BlockedNumbers() {
+        }
+
+        /**
+         * TODO javadoc
+         *
+         * Content URI for the blocked numbers.
+         *
+         * Supported operations
+         * blocked
+         * - query
+         * - delete
+         * - insert
+         *
+         * blocked/ID
+         * - query (selection is not supported)
+         * - delete (selection is not supported)
+         */
+        public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI,
+                "blocked");
+
+        /**
+         * The MIME type of {@link #CONTENT_URI} itself providing a directory of blocked phone
+         * numbers.
+         */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/blocked_numbers";
+
+        /**
+         * The MIME type of a blocked phone number under {@link #CONTENT_URI}.
+         */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/blocked_number";
+
+        /**
+         * Auto-generated ID field which monotonically increases.
+         * <p>TYPE: long</p>
+         */
+        public static final String COLUMN_ID = "_id";
+
+        /**
+         * Phone number to block.
+         * <p>Must be specified in {@code insert}.
+         * <p>TYPE: String</p>
+         */
+        public static final String COLUMN_ORIGINAL_NUMBER = "original_number";
+
+        /**
+         * Phone number to block.  The system generates it from {@link #COLUMN_ORIGINAL_NUMBER}
+         * by removing all formatting characters.
+         * <p>Must NOT be specified in {@code insert}.
+         * <p>TYPE: String</p>
+         */
+        public static final String COLUMN_STRIPPED_NUMBER = "stripped_number";
+
+        /**
+         * Phone number to block.  The system generates it from {@link #COLUMN_ORIGINAL_NUMBER}
+         * by removing all formatting characters.
+         * <p>Optional in {@code insert}.  When not specified, the system tries to generate it
+         * assuming the current country. (Which will still be null if the number is not valid.)
+         * <p>TYPE: String</p>
+         */
+        public static final String COLUMN_E164_NUMBER = "e164_number";
+    }
+
+    /** @hide */
+    public static final String METHOD_IS_BLOCKED = "is_blocked";
+
+    /** @hide */
+    public static final String RES_NUMBER_IS_BLOCKED = "blocked";
+
+    /**
+     * Returns whether a given number is in the blocked list.
+     *
+     * TODO This should probably catch IllegalArgumentException to guard against the case where
+     * the provider is encrypted or the user is not running.
+     * (See addEntryAndRemoveExpiredEntries() in
+     * http://ag/#/c/844426/3/core/java/android/provider/CallLog.java)
+     */
+    public static boolean isBlocked(Context context, String phoneNumber) {
+        final Bundle res = context.getContentResolver().call(AUTHORITY_URI,
+                METHOD_IS_BLOCKED, phoneNumber, null);
+        return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);
+    }
+}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 10432b5..b547432 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -409,6 +409,20 @@
                 "directories_enterprise");
 
         /**
+         * Access file provided by remote directory. It allows both personal and work remote
+         * directory, but not local and invisible diretory.
+         *
+         * It's supported only by a few specific places for referring to contact pictures in the
+         * remote directory. Contact picture URIs, e.g.
+         * {@link PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}, may contain this kind of URI.
+         *
+         * @hide
+         */
+        public static final Uri ENTERPRISE_FILE_URI = Uri.withAppendedPath(AUTHORITY_URI,
+                "directory_file_enterprise");
+
+
+        /**
          * The MIME-type of {@link #CONTENT_URI} providing a directory of
          * contact directories.
          */
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index b2d9b934..8472f78 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -609,7 +609,7 @@
          * This download has successfully completed.
          * Warning: there might be other status values that indicate success
          * in the future.
-         * Use isSucccess() to capture the entire category.
+         * Use isStatusSuccess() to capture the entire category.
          */
         public static final int STATUS_SUCCESS = 200;
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
old mode 100644
new mode 100755
index a6485e4..3042aa9
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4429,6 +4429,13 @@
         public static final String HTTP_PROXY = Global.HTTP_PROXY;
 
         /**
+         * Package designated as always-on VPN provider.
+         *
+         * @hide
+         */
+        public static final String ALWAYS_ON_VPN_APP = "always_on_vpn_app";
+
+        /**
          * Whether applications can be installed for this user via the system's
          * {@link Intent#ACTION_INSTALL_PACKAGE} mechanism.
          *
@@ -7409,6 +7416,9 @@
                 BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX = "bluetooth_a2dp_sink_priority_";
         /** {@hide} */
         public static final String
+                BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_";
+        /** {@hide} */
+        public static final String
                 BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_";
         /** {@hide} */
         public static final String
@@ -7456,10 +7466,12 @@
          * The following keys are supported:
          *
          * <pre>
-         * idle_duration        (long)
+         * idle_duration2       (long)
          * wallclock_threshold  (long)
          * parole_interval      (long)
          * parole_duration      (long)
+         *
+         * idle_duration        (long) // This is deprecated and used to circumvent b/26355386.
          * </pre>
          *
          * <p>
@@ -7509,6 +7521,14 @@
         }
 
         /**
+         * Get the key that retrieves a bluetooth a2dp src's priority.
+         * @hide
+         */
+        public static final String getBluetoothA2dpSrcPriorityKey(String address) {
+            return BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT);
+        }
+
+        /**
          * Get the key that retrieves a bluetooth Input Device's priority.
          * @hide
          */
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index bb46e83..816ecde 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -15,9 +15,6 @@
  */
 package android.service.dreams;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
 import android.annotation.IdRes;
 import android.annotation.LayoutRes;
 import android.annotation.Nullable;
@@ -33,27 +30,32 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.util.MathUtils;
 import android.util.Slog;
 import android.view.ActionMode;
 import android.view.Display;
 import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
-import com.android.internal.policy.PhoneWindow;
 import android.view.SearchEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
 import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
-import android.util.MathUtils;
 
+import com.android.internal.policy.PhoneWindow;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.DumpUtils.Dump;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+
 /**
  * Extend this class to implement a custom dream (available to the user as a "Daydream").
  *
@@ -365,6 +367,11 @@
     @Override
     public void onActionModeFinished(ActionMode mode) {
     }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
+    }
     // end Window.Callback methods
 
     // begin public api
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 88bd283..eff09d6 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -85,6 +85,13 @@
             "android.service.zen.automatic.configurationActivity";
 
     /**
+     * The name of the {@code meta-data} tag containing the maximum number of rule instances that
+     * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
+     */
+    public static final String META_DATA_RULE_INSTANCE_LIMIT =
+            "android.service.zen.automatic.ruleInstanceLimit";
+
+    /**
      * A String rule id extra passed to {@link #META_DATA_CONFIGURATION_ACTIVITY}.
      */
     public static final String EXTRA_RULE_ID = "android.content.automatic.ruleId";
diff --git a/core/java/android/service/quicksettings/IQSService.aidl b/core/java/android/service/quicksettings/IQSService.aidl
index 9991d41..4bfc948 100644
--- a/core/java/android/service/quicksettings/IQSService.aidl
+++ b/core/java/android/service/quicksettings/IQSService.aidl
@@ -27,5 +27,9 @@
     void updateStatusIcon(in Tile tile, in Icon icon,
             String contentDescription);
     void onShowDialog(in Tile tile);
+    void onStartActivity(in Tile tile);
     void setTileMode(in ComponentName component, int mode);
+    boolean isLocked();
+    boolean isSecure();
+    void startUnlockAndRun(in Tile tile);
 }
diff --git a/core/java/android/service/quicksettings/IQSTileService.aidl b/core/java/android/service/quicksettings/IQSTileService.aidl
index 4997f75..bfde870 100644
--- a/core/java/android/service/quicksettings/IQSTileService.aidl
+++ b/core/java/android/service/quicksettings/IQSTileService.aidl
@@ -29,4 +29,5 @@
     void onStartListening();
     void onStopListening();
     void onClick(IBinder wtoken);
+    void onUnlockComplete();
 }
diff --git a/core/java/android/service/quicksettings/Tile.java b/core/java/android/service/quicksettings/Tile.java
index 6104913..85f1955 100644
--- a/core/java/android/service/quicksettings/Tile.java
+++ b/core/java/android/service/quicksettings/Tile.java
@@ -36,10 +36,37 @@
 
     private static final String TAG = "Tile";
 
+    /**
+     * This is the default state of any tile, until updated by the {@link TileService}.
+     * <p>
+     * An unavailable state indicates that for some reason this tile is not currently
+     * available to the user for some reason, and will have no click action.  The tile's
+     * icon will be tinted differently to reflect this state.
+     */
+    public static final int STATE_UNAVAILABLE = 0;
+
+    /**
+     * This represents a tile that is currently in a disabled state but is still interactable.
+     *
+     * A disabled state indicates that the tile is not currently active (e.g. wifi disconnected or
+     * bluetooth disabled), but is still interactable by the user to modify this state.  Tiles
+     * that have boolean states should use this to represent one of their states.  The tile's
+     * icon will be tinted differently to reflect this state, but still be distinct from unavailable.
+     */
+    public static final int STATE_INACTIVE = 1;
+
+    /**
+     * This represents a tile that is currently active. (e.g. wifi is connected, bluetooth is on,
+     * cast is casting).
+     */
+    public static final int STATE_ACTIVE = 2;
+
     private ComponentName mComponentName;
     private Icon mIcon;
     private CharSequence mLabel;
     private CharSequence mContentDescription;
+    // Default to active until clients of the new API can update.
+    private int mState = STATE_ACTIVE;
 
     private IQSService mService;
 
@@ -79,6 +106,29 @@
     }
 
     /**
+     * The current state of the tile.
+     *
+     * @see #STATE_UNAVAILABLE
+     * @see #STATE_INACTIVE
+     * @see #STATE_ACTIVE
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Sets the current state for the tile.
+     *
+     * Does not take effect until {@link #updateTile()} is called.
+     *
+     * @param state One of {@link #STATE_UNAVAILABLE}, {@link #STATE_INACTIVE},
+     * {@link #STATE_ACTIVE}
+     */
+    public void setState(int state) {
+        mState = state;
+    }
+
+    /**
      * Gets the current icon for the tile.
      */
     public Icon getIcon() {
@@ -165,6 +215,7 @@
         } else {
             dest.writeByte((byte) 0);
         }
+        dest.writeInt(mState);
         TextUtils.writeToParcel(mLabel, dest, flags);
         TextUtils.writeToParcel(mContentDescription, dest, flags);
     }
@@ -180,6 +231,7 @@
         } else {
             mIcon = null;
         }
+        mState = source.readInt();
         mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
         mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
     }
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 6b12193..c02465b 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -118,6 +118,7 @@
     private Tile mTile;
     private IBinder mToken;
     private IQSService mService;
+    private Runnable mUnlockRunnable;
 
     @Override
     public void onDestroy() {
@@ -199,6 +200,8 @@
      * This will collapse the Quick Settings panel and show the dialog.
      *
      * @param dialog Dialog to show.
+     *
+     * @see #isLocked()
      */
     public final void showDialog(Dialog dialog) {
         dialog.getWindow().getAttributes().token = mToken;
@@ -211,6 +214,67 @@
     }
 
     /**
+     * Prompts the user to unlock the device before executing the Runnable.
+     * <p>
+     * The user will be prompted for their current security method if applicable
+     * and if successful, runnable will be executed.  The Runnable will not be
+     * executed if the user fails to unlock the device or cancels the operation.
+     */
+    public final void unlockAndRun(Runnable runnable) {
+        mUnlockRunnable = runnable;
+        try {
+            mService.startUnlockAndRun(mTile);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Checks if the device is in a secure state.
+     *
+     * TileServices should detect when the device is secure and change their behavior
+     * accordingly.
+     *
+     * @return true if the device is secure.
+     */
+    public final boolean isSecure() {
+        try {
+            return mService.isSecure();
+        } catch (RemoteException e) {
+            return true;
+        }
+    }
+
+    /**
+     * Checks if the lock screen is showing.
+     *
+     * When a device is locked, then {@link #showDialog} will not present a dialog, as it will
+     * be under the lock screen. If the behavior of the Tile is safe to do while locked,
+     * then the user should use {@link #startActivity} to launch an activity on top of the lock
+     * screen, otherwise the tile should use {@link #unlockAndRun(Runnable)} to give the
+     * user their security challenge.
+     *
+     * @return true if the device is locked.
+     */
+    public final boolean isLocked() {
+        try {
+            return mService.isLocked();
+        } catch (RemoteException e) {
+            return true;
+        }
+    }
+
+    /**
+     * Start an activity while collapsing the panel.
+     */
+    public final void startActivityAndCollapse(Intent intent) {
+        startActivity(intent);
+        try {
+            mService.onStartActivity(mTile);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
      * Gets the {@link Tile} for this service.
      * <p/>
      * This tile may be used to get or set the current state for this
@@ -258,6 +322,11 @@
             public void onClick(IBinder wtoken) throws RemoteException {
                 mHandler.obtainMessage(H.MSG_TILE_CLICKED, wtoken).sendToTarget();
             }
+
+            @Override
+            public void onUnlockComplete() throws RemoteException{
+                mHandler.sendEmptyMessage(H.MSG_UNLOCK_COMPLETE);
+            }
         };
     }
 
@@ -269,6 +338,7 @@
         private static final int MSG_TILE_REMOVED = 5;
         private static final int MSG_TILE_CLICKED = 6;
         private static final int MSG_SET_SERVICE = 7;
+        private static final int MSG_UNLOCK_COMPLETE = 8;
 
         public H(Looper looper) {
             super(looper);
@@ -323,6 +393,11 @@
                     mToken = (IBinder) msg.obj;
                     TileService.this.onClick();
                     break;
+                case MSG_UNLOCK_COMPLETE:
+                    if (mUnlockRunnable != null) {
+                        mUnlockRunnable.run();
+                    }
+                    break;
             }
         }
     }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index d146e5e..cd19607 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -167,6 +167,7 @@
         final Rect mDispatchedOutsets = new Rect();
         final Rect mFinalSystemInsets = new Rect();
         final Rect mFinalStableInsets = new Rect();
+        final Rect mBackdropFrame = new Rect();
         final Configuration mConfiguration = new Configuration();
 
         final WindowManager.LayoutParams mLayout
@@ -675,8 +676,8 @@
                     final int relayoutResult = mSession.relayout(
                         mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                             View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
-                            mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
-                            mSurfaceHolder.mSurface);
+                            mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
+                            mConfiguration, mSurfaceHolder.mSurface);
 
                     if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
                             + ", frame=" + mWinFrame);
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index f9387b3..692d848 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1116,24 +1116,30 @@
     public int getOffsetForHorizontal(int line, float horiz) {
         // TODO: use Paint.getOffsetForAdvance to avoid binary search
         final int lineEndOffset = getLineEnd(line);
+        final int lineStartOffset = getLineStart(line);
+
+        Directions dirs = getLineDirections(line);
+
+        TextLine tl = TextLine.obtain();
+        // XXX: we don't care about tabs as we just use TextLine#getOffsetToLeftRightOf here.
+        tl.set(mPaint, mText, lineStartOffset, lineEndOffset, getParagraphDirection(line), dirs,
+                false, null);
+
         final int max;
         if (line == getLineCount() - 1) {
             max = lineEndOffset;
         } else {
-            max = mPaint.getTextRunCursor(mText, 0, mText.length(),
-                    isRtlCharAt(lineEndOffset) ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR,
-                    lineEndOffset, Paint.CURSOR_BEFORE);
+            max = tl.getOffsetToLeftRightOf(lineEndOffset - lineStartOffset,
+                    !isRtlCharAt(lineEndOffset - 1)) + lineStartOffset;
         }
-        final int min = getLineStart(line);
-        Directions dirs = getLineDirections(line);
-
-        int best = min;
+        int best = lineStartOffset;
         float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
 
         for (int i = 0; i < dirs.mDirections.length; i += 2) {
-            int here = min + dirs.mDirections[i];
+            int here = lineStartOffset + dirs.mDirections[i];
             int there = here + (dirs.mDirections[i+1] & RUN_LENGTH_MASK);
-            int swap = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0 ? -1 : 1;
+            boolean isRtl = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0;
+            int swap = isRtl ? -1 : 1;
 
             if (there > max)
                 there = max;
@@ -1153,23 +1159,23 @@
                 low = here + 1;
 
             if (low < there) {
-                low = getOffsetAtStartOf(low);
+                int aft = tl.getOffsetToLeftRightOf(low - lineStartOffset, isRtl) + lineStartOffset;
+                low = tl.getOffsetToLeftRightOf(aft - lineStartOffset, !isRtl) + lineStartOffset;
+                if (low >= here && low < there) {
+                    float dist = Math.abs(getPrimaryHorizontal(low) - horiz);
+                    if (aft < there) {
+                        float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
 
-                float dist = Math.abs(getPrimaryHorizontal(low) - horiz);
-
-                int aft = TextUtils.getOffsetAfter(mText, low);
-                if (aft < there) {
-                    float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
-
-                    if (other < dist) {
-                        dist = other;
-                        low = aft;
+                        if (other < dist) {
+                            dist = other;
+                            low = aft;
+                        }
                     }
-                }
 
-                if (dist < bestdist) {
-                    bestdist = dist;
-                    best = low;
+                    if (dist < bestdist) {
+                        bestdist = dist;
+                        best = low;
+                    }
                 }
             }
 
@@ -1188,6 +1194,7 @@
             best = max;
         }
 
+        TextLine.recycle(tl);
         return best;
     }
 
@@ -1819,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/text/style/LocaleSpan.java b/core/java/android/text/style/LocaleSpan.java
index d286231..117de774 100644
--- a/core/java/android/text/style/LocaleSpan.java
+++ b/core/java/android/text/style/LocaleSpan.java
@@ -16,30 +16,56 @@
 
 package android.text.style;
 
+import com.android.internal.util.Preconditions;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Paint;
 import android.os.Parcel;
 import android.text.ParcelableSpan;
 import android.text.TextPaint;
 import android.text.TextUtils;
+import android.util.LocaleList;
+
 import java.util.Locale;
 
 /**
  * Changes the {@link Locale} of the text to which the span is attached.
  */
 public class LocaleSpan extends MetricAffectingSpan implements ParcelableSpan {
-    private final Locale mLocale;
+    @NonNull
+    private final LocaleList mLocales;
 
     /**
-     * Creates a LocaleSpan.
-     * @param locale The {@link Locale} of the text to which the span is
-     * attached.
+     * Creates a {@link LocaleSpan} from a well-formed {@link Locale}.  Note that only
+     * {@link Locale} objects that can be created by {@link Locale#forLanguageTag(String)} are
+     * supported.
+     *
+     * <p><b>Caveat:</b> Do not specify any {@link Locale} object that cannot be created by
+     * {@link Locale#forLanguageTag(String)}.  {@code new Locale(" a ", " b c", " d")} is an
+     * example of such a malformed {@link Locale} object.</p>
+     *
+     * @param locale The {@link Locale} of the text to which the span is attached.
+     *
+     * @see #LocaleSpan(LocaleList)
      */
-    public LocaleSpan(Locale locale) {
-        mLocale = locale;
+    public LocaleSpan(@Nullable Locale locale) {
+        mLocales = new LocaleList(locale);
     }
 
-    public LocaleSpan(Parcel src) {
-        mLocale = new Locale(src.readString(), src.readString(), src.readString());
+    /**
+     * Creates a {@link LocaleSpan} from {@link LocaleList}.
+     *
+     * @param locales The {@link LocaleList} of the text to which the span is attached.
+     * @throws NullPointerException if {@code locales} is null
+     */
+    public LocaleSpan(@NonNull LocaleList locales) {
+        Preconditions.checkNotNull(locales, "locales cannot be null");
+        mLocales = locales;
+    }
+
+    public LocaleSpan(Parcel source) {
+        mLocales = LocaleList.CREATOR.createFromParcel(source);
     }
 
     @Override
@@ -64,31 +90,40 @@
 
     /** @hide */
     public void writeToParcelInternal(Parcel dest, int flags) {
-        dest.writeString(mLocale.getLanguage());
-        dest.writeString(mLocale.getCountry());
-        dest.writeString(mLocale.getVariant());
+        mLocales.writeToParcel(dest, flags);
     }
 
     /**
-     * Returns the {@link Locale}.
+     * @return The {@link Locale} for this span.  If multiple locales are associated with this
+     * span, only the first locale is returned.  {@code null} if no {@link Locale} is specified.
      *
-     * @return The {@link Locale} for this span.
+     * @see LocaleList#getPrimary()
+     * @see #getLocales()
      */
+    @Nullable
     public Locale getLocale() {
-        return mLocale;
+        return mLocales.getPrimary();
+    }
+
+    /**
+     * @return The entire list of locales that are associated with this span.
+     */
+    @NonNull
+    public LocaleList getLocales() {
+        return mLocales;
     }
 
     @Override
     public void updateDrawState(TextPaint ds) {
-        apply(ds, mLocale);
+        apply(ds, mLocales);
     }
 
     @Override
     public void updateMeasureState(TextPaint paint) {
-        apply(paint, mLocale);
+        apply(paint, mLocales);
     }
 
-    private static void apply(Paint paint, Locale locale) {
-        paint.setTextLocale(locale);
+    private static void apply(@NonNull Paint paint, @NonNull LocaleList locales) {
+        paint.setTextLocales(locales);
     }
 }
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 6b449f9..1b00db2 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -16,6 +16,8 @@
 
 package android.text.style;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
@@ -84,7 +86,15 @@
 
     private int mFlags;
     private final String[] mSuggestions;
-    private final String mLocaleString;
+    /**
+     * Kept for compatibility for apps that rely on invalid locale strings e.g.
+     * {@code new Locale(" an ", " i n v a l i d ", "data")}, which cannot be handled by
+     * {@link #mLanguageTag}.
+     */
+    @NonNull
+    private final String mLocaleStringForCompatibility;
+    @NonNull
+    private final String mLanguageTag;
     private final String mNotificationTargetClassName;
     private final String mNotificationTargetPackageName;
     private final int mHashCode;
@@ -130,14 +140,18 @@
         final int N = Math.min(SUGGESTIONS_MAX_SIZE, suggestions.length);
         mSuggestions = Arrays.copyOf(suggestions, N);
         mFlags = flags;
+        final Locale sourceLocale;
         if (locale != null) {
-            mLocaleString = locale.toString();
+            sourceLocale = locale;
         } else if (context != null) {
-            mLocaleString = context.getResources().getConfiguration().locale.toString();
+            // TODO: Consider to context.getResources().getResolvedLocale() instead.
+            sourceLocale = context.getResources().getConfiguration().locale;
         } else {
             Log.e("SuggestionSpan", "No locale or context specified in SuggestionSpan constructor");
-            mLocaleString = "";
+            sourceLocale = null;
         }
+        mLocaleStringForCompatibility = sourceLocale == null ? "" : sourceLocale.toString();
+        mLanguageTag = sourceLocale == null ? "" : sourceLocale.toLanguageTag();
 
         if (context != null) {
             mNotificationTargetPackageName = context.getPackageName();
@@ -150,7 +164,8 @@
         } else {
             mNotificationTargetClassName = "";
         }
-        mHashCode = hashCodeInternal(mSuggestions, mLocaleString, mNotificationTargetClassName);
+        mHashCode = hashCodeInternal(mSuggestions, mLanguageTag, mLocaleStringForCompatibility,
+                mNotificationTargetClassName);
 
         initStyle(context);
     }
@@ -194,7 +209,8 @@
     public SuggestionSpan(Parcel src) {
         mSuggestions = src.readStringArray();
         mFlags = src.readInt();
-        mLocaleString = src.readString();
+        mLocaleStringForCompatibility = src.readString();
+        mLanguageTag = src.readString();
         mNotificationTargetClassName = src.readString();
         mNotificationTargetPackageName = src.readString();
         mHashCode = src.readInt();
@@ -214,10 +230,29 @@
     }
 
     /**
-     * @return the locale of the suggestions
+     * @deprecated use {@link #getLocaleObject()} instead.
+     * @return the locale of the suggestions. An empty string is returned if no locale is specified.
      */
+    @NonNull
+    @Deprecated
     public String getLocale() {
-        return mLocaleString;
+        return mLocaleStringForCompatibility;
+    }
+
+    /**
+     * Returns a well-formed BCP 47 language tag representation of the suggestions, as a
+     * {@link Locale} object.
+     *
+     * <p><b>Caveat</b>: The returned object is guaranteed to be a  a well-formed BCP 47 language tag
+     * representation.  For example, this method can return an empty locale rather than returning a
+     * malformed data when this object is initialized with an malformed {@link Locale} object, e.g.
+     * {@code new Locale(" a ", " b c d ", " "}.</p>
+     *
+     * @return the locale of the suggestions. {@code null} is returned if no locale is specified.
+     */
+    @Nullable
+    public Locale getLocaleObject() {
+        return mLanguageTag.isEmpty() ? null : Locale.forLanguageTag(mLanguageTag);
     }
 
     /**
@@ -255,7 +290,8 @@
     public void writeToParcelInternal(Parcel dest, int flags) {
         dest.writeStringArray(mSuggestions);
         dest.writeInt(mFlags);
-        dest.writeString(mLocaleString);
+        dest.writeString(mLocaleStringForCompatibility);
+        dest.writeString(mLanguageTag);
         dest.writeString(mNotificationTargetClassName);
         dest.writeString(mNotificationTargetPackageName);
         dest.writeInt(mHashCode);
@@ -290,10 +326,10 @@
         return mHashCode;
     }
 
-    private static int hashCodeInternal(String[] suggestions, String locale,
-            String notificationTargetClassName) {
+    private static int hashCodeInternal(String[] suggestions, @NonNull String languageTag,
+            @NonNull String localeStringForCompatibility, String notificationTargetClassName) {
         return Arrays.hashCode(new Object[] {Long.valueOf(SystemClock.uptimeMillis()), suggestions,
-                locale, notificationTargetClassName});
+                languageTag, localeStringForCompatibility, notificationTargetClassName});
     }
 
     public static final Parcelable.Creator<SuggestionSpan> CREATOR =
diff --git a/core/java/android/transition/SidePropagation.java b/core/java/android/transition/SidePropagation.java
index b10f6a0..817541c 100644
--- a/core/java/android/transition/SidePropagation.java
+++ b/core/java/android/transition/SidePropagation.java
@@ -16,6 +16,7 @@
 package android.transition;
 
 import android.graphics.Rect;
+import android.transition.Slide.GravityFlag;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -45,7 +46,7 @@
      *             {@link Gravity#LEFT}, {@link Gravity#TOP}, {@link Gravity#RIGHT},
      *             {@link Gravity#BOTTOM}, {@link Gravity#START}, or {@link Gravity#END}.
      */
-    public void setSide(int side) {
+    public void setSide(@GravityFlag int side) {
         mSide = side;
     }
 
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
index 9063b43..9af65e4 100644
--- a/core/java/android/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -17,6 +17,7 @@
 
 import android.animation.Animator;
 import android.animation.TimeInterpolator;
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -27,6 +28,9 @@
 import android.view.animation.DecelerateInterpolator;
 import com.android.internal.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * This transition tracks changes to the visibility of target views in the
  * start and end scenes and moves views in or out from one of the edges of the
@@ -42,7 +46,12 @@
     private static final TimeInterpolator sAccelerate = new AccelerateInterpolator();
     private static final String PROPNAME_SCREEN_POSITION = "android:slide:screenPosition";
     private CalculateSlide mSlideCalculator = sCalculateBottom;
-    private int mSlideEdge = Gravity.BOTTOM;
+    private @GravityFlag int mSlideEdge = Gravity.BOTTOM;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({Gravity.LEFT, Gravity.TOP, Gravity.RIGHT, Gravity.BOTTOM, Gravity.START, Gravity.END})
+    public @interface GravityFlag {}
 
     private interface CalculateSlide {
 
@@ -176,7 +185,7 @@
      *                  {@link android.view.Gravity#START}, {@link android.view.Gravity#END}.
      * @attr ref android.R.styleable#Slide_slideEdge
      */
-    public void setSlideEdge(int slideEdge) {
+    public void setSlideEdge(@GravityFlag int slideEdge) {
         switch (slideEdge) {
             case Gravity.LEFT:
                 mSlideCalculator = sCalculateLeft;
@@ -214,6 +223,7 @@
      *         {@link android.view.Gravity#START}, {@link android.view.Gravity#END}.
      * @attr ref android.R.styleable#Slide_slideEdge
      */
+    @GravityFlag
     public int getSlideEdge() {
         return mSlideEdge;
     }
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index e711812..eb95a02 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -16,17 +16,21 @@
 
 package android.transition;
 
-import com.android.internal.R;
-
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
 import android.animation.Animator.AnimatorPauseListener;
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.internal.R;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * This transition tracks changes to the visibility of target views in the
  * start and end scenes. Visibility is determined not just by the
@@ -46,6 +50,11 @@
     private static final String PROPNAME_PARENT = "android:visibility:parent";
     private static final String PROPNAME_SCREEN_LOCATION = "android:visibility:screenLocation";
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag=true, value={MODE_IN, MODE_OUT})
+    @interface VisibilityMode {}
+
     /**
      * Mode used in {@link #setMode(int)} to make the transition
      * operate on targets that are appearing. Maybe be combined with
@@ -99,7 +108,7 @@
      *             {@link #MODE_IN} and {@link #MODE_OUT}.
      * @attr ref android.R.styleable#VisibilityTransition_transitionVisibilityMode
      */
-    public void setMode(int mode) {
+    public void setMode(@VisibilityMode int mode) {
         if ((mode & ~(MODE_IN | MODE_OUT)) != 0) {
             throw new IllegalArgumentException("Only MODE_IN and MODE_OUT flags are allowed");
         }
@@ -113,6 +122,7 @@
      *         {@link #MODE_IN} and {@link #MODE_OUT}.
      * @attr ref android.R.styleable#VisibilityTransition_transitionVisibilityMode
      */
+    @VisibilityMode
     public int getMode() {
         return mMode;
     }
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 6bda83d2..6196a97 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -23,6 +23,7 @@
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.regex.Matcher;
@@ -161,6 +162,17 @@
                 throw new IllegalArgumentException("Unknown entry type: " + type);
             }
         }
+
+        /** @hide */
+        public static Event fromBytes(byte[] data) {
+            return new Event(data);
+        }
+
+        /** @hide */
+        public byte[] getBytes() {
+            byte[] bytes = mBuffer.array();
+            return Arrays.copyOf(bytes, bytes.length);
+        }
     }
 
     // We assume that the native methods deal with any concurrency issues.
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
new file mode 100644
index 0000000..81c8c45
--- /dev/null
+++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
@@ -0,0 +1,1033 @@
+/*
+ * 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.util.apk;
+
+import android.util.Pair;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.math.BigInteger;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.security.DigestException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * APK Signature Scheme v2 verifier.
+ *
+ * @hide for internal use only.
+ */
+public class ApkSignatureSchemeV2Verifier {
+
+    /**
+     * {@code .SF} file header section attribute indicating that the APK is signed not just with
+     * JAR signature scheme but also with APK Signature Scheme v2 or newer. This attribute
+     * facilitates v2 signature stripping detection.
+     *
+     * <p>The attribute contains a comma-separated set of signature scheme IDs.
+     */
+    public static final String SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME = "X-Android-APK-Signed";
+    // TODO: Change the value when signing scheme finalized.
+    public static final int SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID = 1234567890;
+
+    /**
+     * Verifies APK Signature Scheme v2 signatures of the provided APK and returns the certificates
+     * associated with each signer.
+     *
+     * @throws SignatureNotFoundException if the APK is not signed using APK Signature Scheme v2.
+     * @throws SecurityException if a APK Signature Scheme v2 signature of this APK does not verify.
+     * @throws IOException if an I/O error occurs while reading the APK file.
+     */
+    public static X509Certificate[][] verify(String apkFile)
+            throws SignatureNotFoundException, SecurityException, IOException {
+        try (RandomAccessFile apk = new RandomAccessFile(apkFile, "r")) {
+            return verify(apk);
+        }
+    }
+
+    /**
+     * Verifies APK Signature Scheme v2 signatures of the provided APK and returns the certificates
+     * associated with each signer.
+     *
+     * @throws SignatureNotFoundException if the APK is not signed using APK Signature Scheme v2.
+     * @throws SecurityException if a APK Signature Scheme v2 signature of this APK does not verify.
+     * @throws IOException if an I/O error occurs while reading the APK file.
+     */
+    public static X509Certificate[][] verify(RandomAccessFile apk)
+            throws SignatureNotFoundException, SecurityException, IOException {
+
+        long fileSize = apk.length();
+        if (fileSize > Integer.MAX_VALUE) {
+            throw new IOException("File too large: " + apk.length() + " bytes");
+        }
+        MappedByteBuffer apkContents =
+                apk.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileSize);
+        // Attempt to preload the contents into memory for faster overall verification (v2 and
+        // older) at the expense of somewhat increased latency for rejecting malformed APKs.
+        apkContents.load();
+        return verify(apkContents);
+    }
+
+    /**
+     * Verifies APK Signature Scheme v2 signatures of the provided APK and returns the certificates
+     * associated with each signer.
+     *
+     * @param apkContents contents of the APK. The contents start at the current position and end
+     *        at the limit of the buffer.
+     *
+     * @throws SignatureNotFoundException if the APK is not signed using APK Signature Scheme v2.
+     * @throws SecurityException if a APK Signature Scheme v2 signature of this APK does not verify.
+     */
+    public static X509Certificate[][] verify(ByteBuffer apkContents)
+            throws SignatureNotFoundException, SecurityException {
+        // Avoid modifying byte order, position, limit, and mark of the original apkContents.
+        apkContents = apkContents.slice();
+
+        // ZipUtils and APK Signature Scheme v2 verifier expect little-endian byte order.
+        apkContents.order(ByteOrder.LITTLE_ENDIAN);
+
+        // Find the offset of ZIP End of Central Directory (EoCD)
+        int eocdOffset = ZipUtils.findZipEndOfCentralDirectoryRecord(apkContents);
+        if (eocdOffset == -1) {
+            throw new SignatureNotFoundException(
+                    "Not an APK file: ZIP End of Central Directory record not found");
+        }
+        if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(apkContents, eocdOffset)) {
+            throw new SignatureNotFoundException("ZIP64 APK not supported");
+        }
+        ByteBuffer eocd = sliceFromTo(apkContents, eocdOffset, apkContents.capacity());
+
+        // Look up the offset of ZIP Central Directory.
+        long centralDirOffsetLong = ZipUtils.getZipEocdCentralDirectoryOffset(eocd);
+        if (centralDirOffsetLong >= eocdOffset) {
+            throw new SignatureNotFoundException(
+                    "ZIP Central Directory offset out of range: " + centralDirOffsetLong
+                    + ". ZIP End of Central Directory offset: " + eocdOffset);
+        }
+        long centralDirSizeLong = ZipUtils.getZipEocdCentralDirectorySizeBytes(eocd);
+        if (centralDirOffsetLong + centralDirSizeLong != eocdOffset) {
+            throw new SignatureNotFoundException(
+                    "ZIP Central Directory is not immediately followed by End of Central"
+                    + " Directory");
+        }
+        int centralDirOffset = (int) centralDirOffsetLong;
+
+        // Find the APK Signing Block.
+        int apkSigningBlockOffset = findApkSigningBlock(apkContents, centralDirOffset);
+        ByteBuffer apkSigningBlock =
+                sliceFromTo(apkContents, apkSigningBlockOffset, centralDirOffset);
+
+        // Find the APK Signature Scheme v2 Block inside the APK Signing Block.
+        ByteBuffer apkSignatureSchemeV2Block = findApkSignatureSchemeV2Block(apkSigningBlock);
+
+        // Verify the contents of the APK outside of the APK Signing Block using the APK Signature
+        // Scheme v2 Block.
+        return verify(
+                apkContents,
+                apkSignatureSchemeV2Block,
+                apkSigningBlockOffset,
+                centralDirOffset,
+                eocdOffset);
+    }
+
+    /**
+     * Verifies the contents outside of the APK Signing Block using the provided APK Signature
+     * Scheme v2 Block.
+     */
+    private static X509Certificate[][] verify(
+            ByteBuffer apkContents,
+            ByteBuffer v2Block,
+            int apkSigningBlockOffset,
+            int centralDirOffset,
+            int eocdOffset) throws SecurityException {
+        int signerCount = 0;
+        Map<Integer, byte[]> contentDigests = new HashMap<>();
+        List<X509Certificate[]> signerCerts = new ArrayList<>();
+        CertificateFactory certFactory;
+        try {
+            certFactory = CertificateFactory.getInstance("X.509");
+        } catch (CertificateException e) {
+            throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e);
+        }
+        ByteBuffer signers;
+        try {
+            signers = getLengthPrefixedSlice(v2Block);
+        } catch (IOException e) {
+            throw new SecurityException("Failed to read list of signers", e);
+        }
+        while (signers.hasRemaining()) {
+            signerCount++;
+            try {
+                ByteBuffer signer = getLengthPrefixedSlice(signers);
+                X509Certificate[] certs = verifySigner(signer, contentDigests, certFactory);
+                signerCerts.add(certs);
+            } catch (IOException | BufferUnderflowException | SecurityException e) {
+                throw new SecurityException(
+                        "Failed to parse/verify signer #" + signerCount + " block",
+                        e);
+            }
+        }
+
+        if (signerCount < 1) {
+            throw new SecurityException("No signers found");
+        }
+
+        if (contentDigests.isEmpty()) {
+            throw new SecurityException("No content digests found");
+        }
+
+        verifyIntegrity(
+                contentDigests,
+                apkContents,
+                apkSigningBlockOffset,
+                centralDirOffset,
+                eocdOffset);
+
+        return signerCerts.toArray(new X509Certificate[signerCerts.size()][]);
+    }
+
+    private static X509Certificate[] verifySigner(
+            ByteBuffer signerBlock,
+            Map<Integer, byte[]> contentDigests,
+            CertificateFactory certFactory) throws SecurityException, IOException {
+        ByteBuffer signedData = getLengthPrefixedSlice(signerBlock);
+        ByteBuffer signatures = getLengthPrefixedSlice(signerBlock);
+        byte[] publicKeyBytes = readLengthPrefixedByteArray(signerBlock);
+
+        int signatureCount = 0;
+        int bestSigAlgorithm = -1;
+        byte[] bestSigAlgorithmSignatureBytes = null;
+        List<Integer> signaturesSigAlgorithms = new ArrayList<>();
+        while (signatures.hasRemaining()) {
+            signatureCount++;
+            try {
+                ByteBuffer signature = getLengthPrefixedSlice(signatures);
+                if (signature.remaining() < 8) {
+                    throw new SecurityException("Signature record too short");
+                }
+                int sigAlgorithm = signature.getInt();
+                signaturesSigAlgorithms.add(sigAlgorithm);
+                if (!isSupportedSignatureAlgorithm(sigAlgorithm)) {
+                    continue;
+                }
+                if ((bestSigAlgorithm == -1)
+                        || (compareSignatureAlgorithm(sigAlgorithm, bestSigAlgorithm) > 0)) {
+                    bestSigAlgorithm = sigAlgorithm;
+                    bestSigAlgorithmSignatureBytes = readLengthPrefixedByteArray(signature);
+                }
+            } catch (IOException | BufferUnderflowException e) {
+                throw new SecurityException(
+                        "Failed to parse signature record #" + signatureCount,
+                        e);
+            }
+        }
+        if (bestSigAlgorithm == -1) {
+            if (signatureCount == 0) {
+                throw new SecurityException("No signatures found");
+            } else {
+                throw new SecurityException("No supported signatures found");
+            }
+        }
+
+        String keyAlgorithm = getSignatureAlgorithmJcaKeyAlgorithm(bestSigAlgorithm);
+        Pair<String, ? extends AlgorithmParameterSpec> signatureAlgorithmParams =
+                getSignatureAlgorithmJcaSignatureAlgorithm(bestSigAlgorithm);
+        String jcaSignatureAlgorithm = signatureAlgorithmParams.first;
+        AlgorithmParameterSpec jcaSignatureAlgorithmParams = signatureAlgorithmParams.second;
+        boolean sigVerified;
+        try {
+            PublicKey publicKey =
+                    KeyFactory.getInstance(keyAlgorithm)
+                            .generatePublic(new X509EncodedKeySpec(publicKeyBytes));
+            Signature sig = Signature.getInstance(jcaSignatureAlgorithm);
+            sig.initVerify(publicKey);
+            if (jcaSignatureAlgorithmParams != null) {
+                sig.setParameter(jcaSignatureAlgorithmParams);
+            }
+            sig.update(signedData);
+            sigVerified = sig.verify(bestSigAlgorithmSignatureBytes);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException
+                | InvalidAlgorithmParameterException | SignatureException e) {
+            throw new SecurityException(
+                    "Failed to verify " + jcaSignatureAlgorithm + " signature", e);
+        }
+        if (!sigVerified) {
+            throw new SecurityException(jcaSignatureAlgorithm + " signature did not verify");
+        }
+
+        // Signature over signedData has verified.
+
+        byte[] contentDigest = null;
+        signedData.clear();
+        ByteBuffer digests = getLengthPrefixedSlice(signedData);
+        List<Integer> digestsSigAlgorithms = new ArrayList<>();
+        int digestCount = 0;
+        while (digests.hasRemaining()) {
+            digestCount++;
+            try {
+                ByteBuffer digest = getLengthPrefixedSlice(digests);
+                if (digest.remaining() < 8) {
+                    throw new IOException("Record too short");
+                }
+                int sigAlgorithm = digest.getInt();
+                digestsSigAlgorithms.add(sigAlgorithm);
+                if (sigAlgorithm == bestSigAlgorithm) {
+                    contentDigest = readLengthPrefixedByteArray(digest);
+                }
+            } catch (IOException | BufferUnderflowException e) {
+                throw new IOException("Failed to parse digest record #" + digestCount, e);
+            }
+        }
+
+        if (!signaturesSigAlgorithms.equals(digestsSigAlgorithms)) {
+            throw new SecurityException(
+                    "Signature algorithms don't match between digests and signatures records");
+        }
+        int digestAlgorithm = getSignatureAlgorithmContentDigestAlgorithm(bestSigAlgorithm);
+        byte[] previousSignerDigest = contentDigests.put(digestAlgorithm, contentDigest);
+        if ((previousSignerDigest != null)
+                && (!MessageDigest.isEqual(previousSignerDigest, contentDigest))) {
+            throw new SecurityException(
+                    getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm)
+                    + " contents digest does not match the digest specified by a preceding signer");
+        }
+
+        ByteBuffer certificates = getLengthPrefixedSlice(signedData);
+        List<X509Certificate> certs = new ArrayList<>();
+        int certificateCount = 0;
+        while (certificates.hasRemaining()) {
+            certificateCount++;
+            byte[] encodedCert = readLengthPrefixedByteArray(certificates);
+            X509Certificate certificate;
+            try {
+                certificate = (X509Certificate)
+                        certFactory.generateCertificate(new ByteArrayInputStream(encodedCert));
+            } catch (CertificateException e) {
+                throw new SecurityException("Failed to decode certificate #" + certificateCount, e);
+            }
+            certificate = new VerbatimX509Certificate(certificate, encodedCert);
+            certs.add(certificate);
+        }
+
+        if (certs.isEmpty()) {
+            throw new SecurityException("No certificates listed");
+        }
+        X509Certificate mainCertificate = certs.get(0);
+        byte[] certificatePublicKeyBytes = mainCertificate.getPublicKey().getEncoded();
+        if (!Arrays.equals(publicKeyBytes, certificatePublicKeyBytes)) {
+            throw new SecurityException(
+                    "Public key mismatch between certificate and signature record");
+        }
+
+        return certs.toArray(new X509Certificate[certs.size()]);
+    }
+
+    private static void verifyIntegrity(
+            Map<Integer, byte[]> expectedDigests,
+            ByteBuffer apkContents,
+            int apkSigningBlockOffset,
+            int centralDirOffset,
+            int eocdOffset) throws SecurityException {
+
+        if (expectedDigests.isEmpty()) {
+            throw new SecurityException("No digests provided");
+        }
+
+        ByteBuffer beforeApkSigningBlock = sliceFromTo(apkContents, 0, apkSigningBlockOffset);
+        ByteBuffer centralDir = sliceFromTo(apkContents, centralDirOffset, eocdOffset);
+        // For the purposes of integrity verification, ZIP End of Central Directory's field Start of
+        // Central Directory must be considered to point to the offset of the APK Signing Block.
+        byte[] eocdBytes = new byte[apkContents.capacity() - eocdOffset];
+        apkContents.position(eocdOffset);
+        apkContents.get(eocdBytes);
+        ByteBuffer eocd = ByteBuffer.wrap(eocdBytes);
+        eocd.order(apkContents.order());
+        ZipUtils.setZipEocdCentralDirectoryOffset(eocd, apkSigningBlockOffset);
+
+        int[] digestAlgorithms = new int[expectedDigests.size()];
+        int digestAlgorithmCount = 0;
+        for (int digestAlgorithm : expectedDigests.keySet()) {
+            digestAlgorithms[digestAlgorithmCount] = digestAlgorithm;
+            digestAlgorithmCount++;
+        }
+        Map<Integer, byte[]> actualDigests;
+        try {
+            actualDigests =
+                    computeContentDigests(
+                            digestAlgorithms,
+                            new ByteBuffer[] {beforeApkSigningBlock, centralDir, eocd});
+        } catch (DigestException e) {
+            throw new SecurityException("Failed to compute digest(s) of contents", e);
+        }
+        for (Map.Entry<Integer, byte[]> entry : expectedDigests.entrySet()) {
+            int digestAlgorithm = entry.getKey();
+            byte[] expectedDigest = entry.getValue();
+            byte[] actualDigest = actualDigests.get(digestAlgorithm);
+            if (!MessageDigest.isEqual(expectedDigest, actualDigest)) {
+                throw new SecurityException(
+                        getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm)
+                        + " digest of contents did not verify");
+            }
+        }
+    }
+
+    private static Map<Integer, byte[]> computeContentDigests(
+            int[] digestAlgorithms,
+            ByteBuffer[] contents) throws DigestException {
+        // For each digest algorithm the result is computed as follows:
+        // 1. Each segment of contents is split into consecutive chunks of 1 MB in size.
+        //    The final chunk will be shorter iff the length of segment is not a multiple of 1 MB.
+        //    No chunks are produced for empty (zero length) segments.
+        // 2. The digest of each chunk is computed over the concatenation of byte 0xa5, the chunk's
+        //    length in bytes (uint32 little-endian) and the chunk's contents.
+        // 3. The output digest is computed over the concatenation of the byte 0x5a, the number of
+        //    chunks (uint32 little-endian) and the concatenation of digests of chunks of all
+        //    segments in-order.
+
+        int totalChunkCount = 0;
+        for (ByteBuffer input : contents) {
+            totalChunkCount += getChunkCount(input.remaining());
+        }
+
+        Map<Integer, byte[]> digestsOfChunks = new HashMap<>(totalChunkCount);
+        for (int digestAlgorithm : digestAlgorithms) {
+            int digestOutputSizeBytes = getContentDigestAlgorithmOutputSizeBytes(digestAlgorithm);
+            byte[] concatenationOfChunkCountAndChunkDigests =
+                    new byte[5 + totalChunkCount * digestOutputSizeBytes];
+            concatenationOfChunkCountAndChunkDigests[0] = 0x5a;
+            setUnsignedInt32LittleEndian(
+                    totalChunkCount,
+                    concatenationOfChunkCountAndChunkDigests,
+                    1);
+            digestsOfChunks.put(digestAlgorithm, concatenationOfChunkCountAndChunkDigests);
+        }
+
+        byte[] chunkContentPrefix = new byte[5];
+        chunkContentPrefix[0] = (byte) 0xa5;
+        int chunkIndex = 0;
+        for (ByteBuffer input : contents) {
+            while (input.hasRemaining()) {
+                int chunkSize = Math.min(input.remaining(), CHUNK_SIZE_BYTES);
+                ByteBuffer chunk = getByteBuffer(input, chunkSize);
+                for (int digestAlgorithm : digestAlgorithms) {
+                    String jcaAlgorithmName =
+                            getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm);
+                    MessageDigest md;
+                    try {
+                        md = MessageDigest.getInstance(jcaAlgorithmName);
+                    } catch (NoSuchAlgorithmException e) {
+                        throw new RuntimeException(jcaAlgorithmName + " digest not supported", e);
+                    }
+                    chunk.clear();
+                    setUnsignedInt32LittleEndian(chunk.remaining(), chunkContentPrefix, 1);
+                    md.update(chunkContentPrefix);
+                    md.update(chunk);
+                    byte[] concatenationOfChunkCountAndChunkDigests =
+                            digestsOfChunks.get(digestAlgorithm);
+                    int expectedDigestSizeBytes =
+                            getContentDigestAlgorithmOutputSizeBytes(digestAlgorithm);
+                    int actualDigestSizeBytes = md.digest(concatenationOfChunkCountAndChunkDigests,
+                            5 + chunkIndex * expectedDigestSizeBytes, expectedDigestSizeBytes);
+                    if (actualDigestSizeBytes != expectedDigestSizeBytes) {
+                        throw new RuntimeException(
+                                "Unexpected output size of " + md.getAlgorithm() + " digest: "
+                                        + actualDigestSizeBytes);
+                    }
+                }
+                chunkIndex++;
+            }
+        }
+
+        Map<Integer, byte[]> result = new HashMap<>(digestAlgorithms.length);
+        for (Map.Entry<Integer, byte[]> entry : digestsOfChunks.entrySet()) {
+            int digestAlgorithm = entry.getKey();
+            byte[] input = entry.getValue();
+            String jcaAlgorithmName = getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm);
+            MessageDigest md;
+            try {
+                md = MessageDigest.getInstance(jcaAlgorithmName);
+            } catch (NoSuchAlgorithmException e) {
+                throw new RuntimeException(jcaAlgorithmName + " digest not supported", e);
+            }
+            byte[] output = md.digest(input);
+            result.put(digestAlgorithm, output);
+        }
+        return result;
+    }
+
+    private static final int getChunkCount(int inputSizeBytes) {
+        return (inputSizeBytes + CHUNK_SIZE_BYTES - 1) / CHUNK_SIZE_BYTES;
+    }
+
+    private static final int CHUNK_SIZE_BYTES = 1024 * 1024;
+
+    private static final int SIGNATURE_RSA_PSS_WITH_SHA256 = 0x0101;
+    private static final int SIGNATURE_RSA_PSS_WITH_SHA512 = 0x0102;
+    private static final int SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256 = 0x0103;
+    private static final int SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512 = 0x0104;
+    private static final int SIGNATURE_ECDSA_WITH_SHA256 = 0x0201;
+    private static final int SIGNATURE_ECDSA_WITH_SHA512 = 0x0202;
+    private static final int SIGNATURE_DSA_WITH_SHA256 = 0x0301;
+    private static final int SIGNATURE_DSA_WITH_SHA512 = 0x0302;
+
+    private static final int CONTENT_DIGEST_CHUNKED_SHA256 = 1;
+    private static final int CONTENT_DIGEST_CHUNKED_SHA512 = 2;
+
+    private static boolean isSupportedSignatureAlgorithm(int sigAlgorithm) {
+        switch (sigAlgorithm) {
+            case SIGNATURE_RSA_PSS_WITH_SHA256:
+            case SIGNATURE_RSA_PSS_WITH_SHA512:
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
+            case SIGNATURE_ECDSA_WITH_SHA256:
+            case SIGNATURE_ECDSA_WITH_SHA512:
+            case SIGNATURE_DSA_WITH_SHA256:
+            case SIGNATURE_DSA_WITH_SHA512:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static int compareSignatureAlgorithm(int sigAlgorithm1, int sigAlgorithm2) {
+        int digestAlgorithm1 = getSignatureAlgorithmContentDigestAlgorithm(sigAlgorithm1);
+        int digestAlgorithm2 = getSignatureAlgorithmContentDigestAlgorithm(sigAlgorithm2);
+        return compareContentDigestAlgorithm(digestAlgorithm1, digestAlgorithm2);
+    }
+
+    private static int compareContentDigestAlgorithm(int digestAlgorithm1, int digestAlgorithm2) {
+        switch (digestAlgorithm1) {
+            case CONTENT_DIGEST_CHUNKED_SHA256:
+                switch (digestAlgorithm2) {
+                    case CONTENT_DIGEST_CHUNKED_SHA256:
+                        return 0;
+                    case CONTENT_DIGEST_CHUNKED_SHA512:
+                        return -1;
+                    default:
+                        throw new IllegalArgumentException(
+                                "Unknown digestAlgorithm2: " + digestAlgorithm2);
+                }
+            case CONTENT_DIGEST_CHUNKED_SHA512:
+                switch (digestAlgorithm2) {
+                    case CONTENT_DIGEST_CHUNKED_SHA256:
+                        return 1;
+                    case CONTENT_DIGEST_CHUNKED_SHA512:
+                        return 0;
+                    default:
+                        throw new IllegalArgumentException(
+                                "Unknown digestAlgorithm2: " + digestAlgorithm2);
+                }
+            default:
+                throw new IllegalArgumentException("Unknown digestAlgorithm1: " + digestAlgorithm1);
+        }
+    }
+
+    private static int getSignatureAlgorithmContentDigestAlgorithm(int sigAlgorithm) {
+        switch (sigAlgorithm) {
+            case SIGNATURE_RSA_PSS_WITH_SHA256:
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
+            case SIGNATURE_ECDSA_WITH_SHA256:
+            case SIGNATURE_DSA_WITH_SHA256:
+                return CONTENT_DIGEST_CHUNKED_SHA256;
+            case SIGNATURE_RSA_PSS_WITH_SHA512:
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
+            case SIGNATURE_ECDSA_WITH_SHA512:
+            case SIGNATURE_DSA_WITH_SHA512:
+                return CONTENT_DIGEST_CHUNKED_SHA512;
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown signature algorithm: 0x"
+                                + Long.toHexString(sigAlgorithm & 0xffffffff));
+        }
+    }
+
+    private static String getContentDigestAlgorithmJcaDigestAlgorithm(int digestAlgorithm) {
+        switch (digestAlgorithm) {
+            case CONTENT_DIGEST_CHUNKED_SHA256:
+                return "SHA-256";
+            case CONTENT_DIGEST_CHUNKED_SHA512:
+                return "SHA-512";
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown content digest algorthm: " + digestAlgorithm);
+        }
+    }
+
+    private static int getContentDigestAlgorithmOutputSizeBytes(int digestAlgorithm) {
+        switch (digestAlgorithm) {
+            case CONTENT_DIGEST_CHUNKED_SHA256:
+                return 256 / 8;
+            case CONTENT_DIGEST_CHUNKED_SHA512:
+                return 512 / 8;
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown content digest algorthm: " + digestAlgorithm);
+        }
+    }
+
+    private static String getSignatureAlgorithmJcaKeyAlgorithm(int sigAlgorithm) {
+        switch (sigAlgorithm) {
+            case SIGNATURE_RSA_PSS_WITH_SHA256:
+            case SIGNATURE_RSA_PSS_WITH_SHA512:
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
+                return "RSA";
+            case SIGNATURE_ECDSA_WITH_SHA256:
+            case SIGNATURE_ECDSA_WITH_SHA512:
+                return "EC";
+            case SIGNATURE_DSA_WITH_SHA256:
+            case SIGNATURE_DSA_WITH_SHA512:
+                return "DSA";
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown signature algorithm: 0x"
+                                + Long.toHexString(sigAlgorithm & 0xffffffff));
+        }
+    }
+
+    private static Pair<String, ? extends AlgorithmParameterSpec>
+            getSignatureAlgorithmJcaSignatureAlgorithm(int sigAlgorithm) {
+        switch (sigAlgorithm) {
+            case SIGNATURE_RSA_PSS_WITH_SHA256:
+                return Pair.create(
+                        "SHA256withRSA/PSS",
+                        new PSSParameterSpec(
+                                "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 256 / 8, 1));
+            case SIGNATURE_RSA_PSS_WITH_SHA512:
+                return Pair.create(
+                        "SHA512withRSA/PSS",
+                        new PSSParameterSpec(
+                                "SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 512 / 8, 1));
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
+                return Pair.create("SHA256withRSA", null);
+            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
+                return Pair.create("SHA512withRSA", null);
+            case SIGNATURE_ECDSA_WITH_SHA256:
+                return Pair.create("SHA256withECDSA", null);
+            case SIGNATURE_ECDSA_WITH_SHA512:
+                return Pair.create("SHA512withECDSA", null);
+            case SIGNATURE_DSA_WITH_SHA256:
+                return Pair.create("SHA256withDSA", null);
+            case SIGNATURE_DSA_WITH_SHA512:
+                return Pair.create("SHA512withDSA", null);
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown signature algorithm: 0x"
+                                + Long.toHexString(sigAlgorithm & 0xffffffff));
+        }
+    }
+
+    /**
+     * Returns new byte buffer whose content is a shared subsequence of this buffer's content
+     * between the specified start (inclusive) and end (exclusive) positions. As opposed to
+     * {@link ByteBuffer#slice()}, the returned buffer's byte order is the same as the source
+     * buffer's byte order.
+     */
+    private static ByteBuffer sliceFromTo(ByteBuffer source, int start, int end) {
+        if (start < 0) {
+            throw new IllegalArgumentException("start: " + start);
+        }
+        if (end < start) {
+            throw new IllegalArgumentException("end < start: " + end + " < " + start);
+        }
+        int capacity = source.capacity();
+        if (end > source.capacity()) {
+            throw new IllegalArgumentException("end > capacity: " + end + " > " + capacity);
+        }
+        int originalLimit = source.limit();
+        int originalPosition = source.position();
+        try {
+            source.position(0);
+            source.limit(end);
+            source.position(start);
+            ByteBuffer result = source.slice();
+            result.order(source.order());
+            return result;
+        } finally {
+            source.position(0);
+            source.limit(originalLimit);
+            source.position(originalPosition);
+        }
+    }
+
+    /**
+     * Relative <em>get</em> method for reading {@code size} number of bytes from the current
+     * position of this buffer.
+     *
+     * <p>This method reads the next {@code size} bytes at this buffer's current position,
+     * returning them as a {@code ByteBuffer} with start set to 0, limit and capacity set to
+     * {@code size}, byte order set to this buffer's byte order; and then increments the position by
+     * {@code size}.
+     */
+    private static ByteBuffer getByteBuffer(ByteBuffer source, int size)
+            throws BufferUnderflowException {
+        if (size < 0) {
+            throw new IllegalArgumentException("size: " + size);
+        }
+        int originalLimit = source.limit();
+        int position = source.position();
+        int limit = position + size;
+        if ((limit < position) || (limit > originalLimit)) {
+            throw new BufferUnderflowException();
+        }
+        source.limit(limit);
+        try {
+            ByteBuffer result = source.slice();
+            result.order(source.order());
+            source.position(limit);
+            return result;
+        } finally {
+            source.limit(originalLimit);
+        }
+    }
+
+    private static ByteBuffer getLengthPrefixedSlice(ByteBuffer source) throws IOException {
+        if (source.remaining() < 4) {
+            throw new IOException(
+                    "Remaining buffer too short to contain length of length-prefixed field."
+                            + " Remaining: " + source.remaining());
+        }
+        int len = source.getInt();
+        if (len < 0) {
+            throw new IllegalArgumentException("Negative length");
+        } else if (len > source.remaining()) {
+            throw new IOException("Length-prefixed field longer than remaining buffer."
+                    + " Field length: " + len + ", remaining: " + source.remaining());
+        }
+        return getByteBuffer(source, len);
+    }
+
+    private static byte[] readLengthPrefixedByteArray(ByteBuffer buf) throws IOException {
+        int len = buf.getInt();
+        if (len < 0) {
+            throw new IOException("Negative length");
+        } else if (len > buf.remaining()) {
+            throw new IOException("Underflow while reading length-prefixed value. Length: " + len
+                    + ", available: " + buf.remaining());
+        }
+        byte[] result = new byte[len];
+        buf.get(result);
+        return result;
+    }
+
+    private static void setUnsignedInt32LittleEndian(int value, byte[] result, int offset) {
+        result[offset] = (byte) (value & 0xff);
+        result[offset + 1] = (byte) ((value >>> 8) & 0xff);
+        result[offset + 2] = (byte) ((value >>> 16) & 0xff);
+        result[offset + 3] = (byte) ((value >>> 24) & 0xff);
+    }
+
+    private static final long APK_SIG_BLOCK_MAGIC_HI = 0x3234206b636f6c42L;
+    private static final long APK_SIG_BLOCK_MAGIC_LO = 0x20676953204b5041L;
+    private static final int APK_SIG_BLOCK_MIN_SIZE = 32;
+
+    private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;
+
+    private static int findApkSigningBlock(ByteBuffer apkContents, int centralDirOffset)
+            throws SignatureNotFoundException {
+        checkByteOrderLittleEndian(apkContents);
+
+        // FORMAT:
+        // OFFSET       DATA TYPE  DESCRIPTION
+        // * @+0  bytes uint64:    size in bytes (excluding this field)
+        // * @+8  bytes payload
+        // * @-24 bytes uint64:    size in bytes (same as the one above)
+        // * @-16 bytes uint128:   magic
+
+        if (centralDirOffset < APK_SIG_BLOCK_MIN_SIZE) {
+            throw new SignatureNotFoundException(
+                    "APK too small for APK Signing Block. ZIP Central Directory offset: "
+                            + centralDirOffset);
+        }
+        // Check magic field present
+        if ((apkContents.getLong(centralDirOffset - 16) != APK_SIG_BLOCK_MAGIC_LO)
+                || (apkContents.getLong(centralDirOffset - 8) != APK_SIG_BLOCK_MAGIC_HI)) {
+            throw new SignatureNotFoundException(
+                    "No APK Signing Block before ZIP Central Directory");
+        }
+        // Read and compare size fields
+        long apkSigBlockSizeLong = apkContents.getLong(centralDirOffset - 24);
+        if ((apkSigBlockSizeLong < 24) || (apkSigBlockSizeLong > Integer.MAX_VALUE - 8)) {
+            throw new SignatureNotFoundException(
+                    "APK Signing Block size out of range: " + apkSigBlockSizeLong);
+        }
+        int apkSigBlockSizeFromFooter = (int) apkSigBlockSizeLong;
+        int totalSize = apkSigBlockSizeFromFooter + 8;
+        int apkSigBlockOffset = centralDirOffset - totalSize;
+        if (apkSigBlockOffset < 0) {
+            throw new SignatureNotFoundException(
+                    "APK Signing Block offset out of range: " + apkSigBlockOffset);
+        }
+        long apkSigBlockSizeFromHeader = apkContents.getLong(apkSigBlockOffset);
+        if (apkSigBlockSizeFromHeader != apkSigBlockSizeFromFooter) {
+            throw new SignatureNotFoundException(
+                    "APK Signing Block sizes in header and footer do not match: "
+                            + apkSigBlockSizeFromHeader + " vs " + apkSigBlockSizeFromFooter);
+        }
+        return apkSigBlockOffset;
+    }
+
+    private static ByteBuffer findApkSignatureSchemeV2Block(ByteBuffer apkSigningBlock)
+            throws SignatureNotFoundException {
+        checkByteOrderLittleEndian(apkSigningBlock);
+        // FORMAT:
+        // OFFSET       DATA TYPE  DESCRIPTION
+        // * @+0  bytes uint64:    size in bytes (excluding this field)
+        // * @+8  bytes pairs
+        // * @-24 bytes uint64:    size in bytes (same as the one above)
+        // * @-16 bytes uint128:   magic
+        ByteBuffer pairs = sliceFromTo(apkSigningBlock, 8, apkSigningBlock.capacity() - 24);
+
+        int entryCount = 0;
+        while (pairs.hasRemaining()) {
+            entryCount++;
+            if (pairs.remaining() < 8) {
+                throw new SignatureNotFoundException(
+                        "Insufficient data to read size of APK Signing Block entry #" + entryCount);
+            }
+            long lenLong = pairs.getLong();
+            if ((lenLong < 4) || (lenLong > Integer.MAX_VALUE)) {
+                throw new SignatureNotFoundException(
+                        "APK Signing Block entry #" + entryCount
+                                + " size out of range: " + lenLong);
+            }
+            int len = (int) lenLong;
+            int nextEntryPos = pairs.position() + len;
+            if (len > pairs.remaining()) {
+                throw new SignatureNotFoundException(
+                        "APK Signing Block entry #" + entryCount + " size out of range: " + len
+                                + ", available: " + pairs.remaining());
+            }
+            int id = pairs.getInt();
+            if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) {
+                return getByteBuffer(pairs, len - 4);
+            }
+            pairs.position(nextEntryPos);
+        }
+
+        throw new SignatureNotFoundException(
+                "No APK Signature Scheme v2 block in APK Signing Block");
+    }
+
+    private static void checkByteOrderLittleEndian(ByteBuffer buffer) {
+        if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
+            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
+        }
+    }
+
+    public static class SignatureNotFoundException extends Exception {
+        public SignatureNotFoundException(String message) {
+            super(message);
+        }
+
+        public SignatureNotFoundException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+
+    /**
+     * For legacy reasons we need to return exactly the original encoded certificate bytes, instead
+     * of letting the underlying implementation have a shot at re-encoding the data.
+     */
+    private static class VerbatimX509Certificate extends WrappedX509Certificate {
+        private byte[] encodedVerbatim;
+
+        public VerbatimX509Certificate(X509Certificate wrapped, byte[] encodedVerbatim) {
+            super(wrapped);
+            this.encodedVerbatim = encodedVerbatim;
+        }
+
+        @Override
+        public byte[] getEncoded() throws CertificateEncodingException {
+            return encodedVerbatim;
+        }
+    }
+
+    private static class WrappedX509Certificate extends X509Certificate {
+        private final X509Certificate wrapped;
+
+        public WrappedX509Certificate(X509Certificate wrapped) {
+            this.wrapped = wrapped;
+        }
+
+        @Override
+        public Set<String> getCriticalExtensionOIDs() {
+            return wrapped.getCriticalExtensionOIDs();
+        }
+
+        @Override
+        public byte[] getExtensionValue(String oid) {
+            return wrapped.getExtensionValue(oid);
+        }
+
+        @Override
+        public Set<String> getNonCriticalExtensionOIDs() {
+            return wrapped.getNonCriticalExtensionOIDs();
+        }
+
+        @Override
+        public boolean hasUnsupportedCriticalExtension() {
+            return wrapped.hasUnsupportedCriticalExtension();
+        }
+
+        @Override
+        public void checkValidity()
+                throws CertificateExpiredException, CertificateNotYetValidException {
+            wrapped.checkValidity();
+        }
+
+        @Override
+        public void checkValidity(Date date)
+                throws CertificateExpiredException, CertificateNotYetValidException {
+            wrapped.checkValidity(date);
+        }
+
+        @Override
+        public int getVersion() {
+            return wrapped.getVersion();
+        }
+
+        @Override
+        public BigInteger getSerialNumber() {
+            return wrapped.getSerialNumber();
+        }
+
+        @Override
+        public Principal getIssuerDN() {
+            return wrapped.getIssuerDN();
+        }
+
+        @Override
+        public Principal getSubjectDN() {
+            return wrapped.getSubjectDN();
+        }
+
+        @Override
+        public Date getNotBefore() {
+            return wrapped.getNotBefore();
+        }
+
+        @Override
+        public Date getNotAfter() {
+            return wrapped.getNotAfter();
+        }
+
+        @Override
+        public byte[] getTBSCertificate() throws CertificateEncodingException {
+            return wrapped.getTBSCertificate();
+        }
+
+        @Override
+        public byte[] getSignature() {
+            return wrapped.getSignature();
+        }
+
+        @Override
+        public String getSigAlgName() {
+            return wrapped.getSigAlgName();
+        }
+
+        @Override
+        public String getSigAlgOID() {
+            return wrapped.getSigAlgOID();
+        }
+
+        @Override
+        public byte[] getSigAlgParams() {
+            return wrapped.getSigAlgParams();
+        }
+
+        @Override
+        public boolean[] getIssuerUniqueID() {
+            return wrapped.getIssuerUniqueID();
+        }
+
+        @Override
+        public boolean[] getSubjectUniqueID() {
+            return wrapped.getSubjectUniqueID();
+        }
+
+        @Override
+        public boolean[] getKeyUsage() {
+            return wrapped.getKeyUsage();
+        }
+
+        @Override
+        public int getBasicConstraints() {
+            return wrapped.getBasicConstraints();
+        }
+
+        @Override
+        public byte[] getEncoded() throws CertificateEncodingException {
+            return wrapped.getEncoded();
+        }
+
+        @Override
+        public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
+                InvalidKeyException, NoSuchProviderException, SignatureException {
+            wrapped.verify(key);
+        }
+
+        @Override
+        public void verify(PublicKey key, String sigProvider)
+                throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
+                NoSuchProviderException, SignatureException {
+            wrapped.verify(key, sigProvider);
+        }
+
+        @Override
+        public String toString() {
+            return wrapped.toString();
+        }
+
+        @Override
+        public PublicKey getPublicKey() {
+            return wrapped.getPublicKey();
+        }
+    }
+}
diff --git a/core/java/android/util/apk/ZipUtils.java b/core/java/android/util/apk/ZipUtils.java
new file mode 100644
index 0000000..a383d5c
--- /dev/null
+++ b/core/java/android/util/apk/ZipUtils.java
@@ -0,0 +1,163 @@
+/*
+ * 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.util.apk;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Assorted ZIP format helpers.
+ *
+ * <p>NOTE: Most helper methods operating on {@code ByteBuffer} instances except that the byte
+ * order of these buffers is little-endian.
+ */
+abstract class ZipUtils {
+    private ZipUtils() {}
+
+    private static final int ZIP_EOCD_REC_MIN_SIZE = 22;
+    private static final int ZIP_EOCD_REC_SIG = 0x06054b50;
+    private static final int ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET = 12;
+    private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET = 16;
+    private static final int ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET = 20;
+
+    private static final int ZIP64_EOCD_LOCATOR_SIZE = 20;
+    private static final int ZIP64_EOCD_LOCATOR_SIG = 0x07064b50;
+
+    private static final int UINT32_MAX_VALUE = 0xffff;
+
+    /**
+     * Returns the position at which ZIP End of Central Directory record starts in the provided
+     * buffer or {@code -1} if the record is not present.
+     *
+     * <p>NOTE: Byte order of {@code zipContents} must be little-endian.
+     */
+    public static int findZipEndOfCentralDirectoryRecord(ByteBuffer zipContents) {
+        assertByteOrderLittleEndian(zipContents);
+
+        // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive.
+        // The record can be identified by its 4-byte signature/magic which is located at the very
+        // beginning of the record. A complication is that the record is variable-length because of
+        // the comment field.
+        // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from
+        // end of the buffer for the EOCD record signature. Whenever we find a signature, we check
+        // the candidate record's comment length is such that the remainder of the record takes up
+        // exactly the remaining bytes in the buffer. The search is bounded because the maximum
+        // size of the comment field is 65535 bytes because the field is an unsigned 32-bit number.
+
+        int archiveSize = zipContents.capacity();
+        if (archiveSize < ZIP_EOCD_REC_MIN_SIZE) {
+            System.out.println("File size smaller than EOCD min size");
+            return -1;
+        }
+        int maxCommentLength = Math.min(archiveSize - ZIP_EOCD_REC_MIN_SIZE, UINT32_MAX_VALUE);
+        int eocdWithEmptyCommentStartPosition = archiveSize - ZIP_EOCD_REC_MIN_SIZE;
+        for (int expectedCommentLength = 0; expectedCommentLength < maxCommentLength;
+                expectedCommentLength++) {
+            int eocdStartPos = eocdWithEmptyCommentStartPosition - expectedCommentLength;
+            if (zipContents.getInt(eocdStartPos) == ZIP_EOCD_REC_SIG) {
+                int actualCommentLength =
+                        getUnsignedInt16(
+                                zipContents, eocdStartPos + ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET);
+                if (actualCommentLength == expectedCommentLength) {
+                    return eocdStartPos;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns {@code true} if the provided buffer contains a ZIP64 End of Central Directory
+     * Locator.
+     *
+     * <p>NOTE: Byte order of {@code zipContents} must be little-endian.
+     */
+    public static final boolean isZip64EndOfCentralDirectoryLocatorPresent(
+            ByteBuffer zipContents, int zipEndOfCentralDirectoryPosition) {
+        assertByteOrderLittleEndian(zipContents);
+
+        // ZIP64 End of Central Directory Locator immediately precedes the ZIP End of Central
+        // Directory Record.
+
+        int locatorPosition = zipEndOfCentralDirectoryPosition - ZIP64_EOCD_LOCATOR_SIZE;
+        if (locatorPosition < 0) {
+            return false;
+        }
+
+        return zipContents.getInt(locatorPosition) == ZIP64_EOCD_LOCATOR_SIG;
+    }
+
+    /**
+     * Returns the offset of the start of the ZIP Central Directory in the archive.
+     *
+     * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
+     */
+    public static long getZipEocdCentralDirectoryOffset(ByteBuffer zipEndOfCentralDirectory) {
+        assertByteOrderLittleEndian(zipEndOfCentralDirectory);
+        return getUnsignedInt32(
+                zipEndOfCentralDirectory,
+                zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET);
+    }
+
+    /**
+     * Sets the offset of the start of the ZIP Central Directory in the archive.
+     *
+     * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
+     */
+    public static void setZipEocdCentralDirectoryOffset(
+            ByteBuffer zipEndOfCentralDirectory, long offset) {
+        assertByteOrderLittleEndian(zipEndOfCentralDirectory);
+        setUnsignedInt32(
+                zipEndOfCentralDirectory,
+                zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET,
+                offset);
+    }
+
+    /**
+     * Returns the size (in bytes) of the ZIP Central Directory.
+     *
+     * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
+     */
+    public static long getZipEocdCentralDirectorySizeBytes(ByteBuffer zipEndOfCentralDirectory) {
+        assertByteOrderLittleEndian(zipEndOfCentralDirectory);
+        return getUnsignedInt32(
+                zipEndOfCentralDirectory,
+                zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET);
+    }
+
+    private static void assertByteOrderLittleEndian(ByteBuffer buffer) {
+        if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
+            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
+        }
+    }
+
+    private static int getUnsignedInt16(ByteBuffer buffer, int offset) {
+        return buffer.getShort(offset) & 0xffff;
+    }
+
+    private static long getUnsignedInt32(ByteBuffer buffer, int offset) {
+        return buffer.getInt(offset) & 0xffffffffL;
+    }
+
+    private static void setUnsignedInt32(ByteBuffer buffer, int offset, long value) {
+        if ((value < 0) || (value > 0xffffffffL)) {
+            throw new IllegalArgumentException("uint32 value of out range: " + value);
+        }
+        buffer.putInt(buffer.position() + offset, (int) value);
+    }
+}
diff --git a/core/java/android/util/jar/StrictJarFile.java b/core/java/android/util/jar/StrictJarFile.java
index fd57806..302a08d 100644
--- a/core/java/android/util/jar/StrictJarFile.java
+++ b/core/java/android/util/jar/StrictJarFile.java
@@ -18,7 +18,6 @@
 package android.util.jar;
 
 import dalvik.system.CloseGuard;
-import java.io.ByteArrayInputStream;
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -30,9 +29,7 @@
 import java.util.zip.Inflater;
 import java.util.zip.InflaterInputStream;
 import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 import java.util.jar.JarFile;
-import java.util.jar.Manifest;
 import libcore.io.IoUtils;
 import libcore.io.Streams;
 
@@ -59,7 +56,13 @@
     private final CloseGuard guard = CloseGuard.get();
     private boolean closed;
 
-    public StrictJarFile(String fileName) throws IOException, SecurityException {
+    public StrictJarFile(String fileName)
+            throws IOException, SecurityException {
+        this(fileName, true);
+    }
+
+    public StrictJarFile(String fileName, boolean verify)
+            throws IOException, SecurityException {
         this.nativeHandle = nativeOpenJarFile(fileName);
         this.raf = new RandomAccessFile(fileName, "r");
 
@@ -67,17 +70,23 @@
             // Read the MANIFEST and signature files up front and try to
             // parse them. We never want to accept a JAR File with broken signatures
             // or manifests, so it's best to throw as early as possible.
-            HashMap<String, byte[]> metaEntries = getMetaEntries();
-            this.manifest = new StrictJarManifest(metaEntries.get(JarFile.MANIFEST_NAME), true);
-            this.verifier = new StrictJarVerifier(fileName, manifest, metaEntries);
-            Set<String> files = manifest.getEntries().keySet();
-            for (String file : files) {
-                if (findEntry(file) == null) {
-                    throw new SecurityException(fileName + ": File " + file + " in manifest does not exist");
+            if (verify) {
+                HashMap<String, byte[]> metaEntries = getMetaEntries();
+                this.manifest = new StrictJarManifest(metaEntries.get(JarFile.MANIFEST_NAME), true);
+                this.verifier = new StrictJarVerifier(fileName, manifest, metaEntries);
+                Set<String> files = manifest.getEntries().keySet();
+                for (String file : files) {
+                    if (findEntry(file) == null) {
+                        throw new SecurityException(fileName + ": File " + file + " in manifest does not exist");
+                    }
                 }
-            }
 
-            isSigned = verifier.readCertificates() && verifier.isSignedJar();
+                isSigned = verifier.readCertificates() && verifier.isSignedJar();
+            } else {
+                isSigned = false;
+                this.manifest = null;
+                this.verifier = null;
+            }
         } catch (IOException | SecurityException e) {
             nativeClose(this.nativeHandle);
             IoUtils.closeQuietly(this.raf);
diff --git a/core/java/android/util/jar/StrictJarVerifier.java b/core/java/android/util/jar/StrictJarVerifier.java
index ca2aec1..0546a5f 100644
--- a/core/java/android/util/jar/StrictJarVerifier.java
+++ b/core/java/android/util/jar/StrictJarVerifier.java
@@ -32,8 +32,12 @@
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
 import java.util.jar.Attributes;
 import java.util.jar.JarFile;
+import android.util.ArraySet;
+import android.util.apk.ApkSignatureSchemeV2Verifier;
 import libcore.io.Base64;
 import sun.security.jca.Providers;
 import sun.security.pkcs.PKCS7;
@@ -353,6 +357,43 @@
             return;
         }
 
+        // Check whether APK Signature Scheme v2 signature was stripped.
+        String apkSignatureSchemeIdList =
+                attributes.getValue(
+                        ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME);
+        if (apkSignatureSchemeIdList != null) {
+            // This field contains a comma-separated list of APK signature scheme IDs which were
+            // used to sign this APK. If an ID is known to us, it means signatures of that scheme
+            // were stripped from the APK because otherwise we wouldn't have fallen back to
+            // verifying the APK using the JAR signature scheme.
+            boolean v2SignatureGenerated = false;
+            StringTokenizer tokenizer = new StringTokenizer(apkSignatureSchemeIdList, ",");
+            while (tokenizer.hasMoreTokens()) {
+                String idText = tokenizer.nextToken().trim();
+                if (idText.isEmpty()) {
+                    continue;
+                }
+                int id;
+                try {
+                    id = Integer.parseInt(idText);
+                } catch (Exception ignored) {
+                    continue;
+                }
+                if (id == ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID) {
+                    // This APK was supposed to be signed with APK Signature Scheme v2 but no such
+                    // signature was found.
+                    v2SignatureGenerated = true;
+                    break;
+                }
+            }
+
+            if (v2SignatureGenerated) {
+                throw new SecurityException(signatureFile + " indicates " + jarName + " is signed"
+                        + " using APK Signature Scheme v2, but no such signature was found."
+                        + " Signature stripped?");
+            }
+        }
+
         // Do we actually have any signatures to look at?
         if (attributes.get(Attributes.Name.SIGNATURE_VERSION) == null) {
             return;
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 9e478c1..9231394 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -25,6 +25,8 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
+import com.android.internal.os.IResultReceiver;
+
 /**
  * API back to a client window that the Window Manager uses to inform it of
  * interesting things happening.
@@ -83,4 +85,9 @@
      * Called for non-application windows when the enter animation has completed.
      */
     void dispatchWindowShown();
+
+    /**
+     * Called when Keyboard Shortcuts are requested for the window.
+     */
+    void requestAppKeyboardShortcuts(IResultReceiver receiver);
 }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 84d312d..b045c17 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -17,6 +17,7 @@
 package android.view;
 
 import com.android.internal.app.IAssistScreenshotReceiver;
+import com.android.internal.os.IResultReceiver;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
 
@@ -370,4 +371,11 @@
      * @param alpha The translucency of the dim layer, between 0 and 1.
      */
     void setResizeDimLayer(boolean visible, int targetStackId, float alpha);
+
+    /**
+     * Requests Keyboard Shortcuts from the displayed window.
+     *
+     * @param receiver The receiver to deliver the results to.
+     */
+    void requestAppKeyboardShortcuts(IResultReceiver receiver);
 }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index b3cd8c11..1a5de7e 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -81,6 +81,8 @@
      * so complex relayout of the window should not happen based on them.
      * @param outOutsets Rect in which is placed the dead area of the screen that we would like to
      * treat as real display. Example of such area is a chin in some models of wearable devices.
+     * @param outBackdropFrame Rect which is used draw the resizing background during a resize
+     * operation.
      * @param outConfiguration New configuration of window, if it is now
      * becoming visible and the global configuration has changed since it
      * was last displayed.
@@ -93,7 +95,8 @@
             int requestedWidth, int requestedHeight, int viewVisibility,
             int flags, out Rect outFrame, out Rect outOverscanInsets,
             out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
-            out Rect outOutsets, out Configuration outConfig, out Surface outSurface);
+            out Rect outOutsets, out Rect outBackdropFrame, out Configuration outConfig,
+            out Surface outSurface);
 
     /**
      *  Position a window relative to it's parent (attached) window without triggering
@@ -120,6 +123,14 @@
     void repositionChild(IWindow childWindow, int left, int top, int right, int bottom,
             long deferTransactionUntilFrame, out Rect outFrame);
 
+    /*
+     * Notify the window manager that an application is relaunching and
+     * child windows should be prepared for replacement.
+     *
+     * @param appToken The application
+     */
+    void prepareToReplaceChildren(IBinder appToken);
+
     /**
      * If a call to relayout() asked to have the surface destroy deferred,
      * it must call this once it is okay to destroy that surface.
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index f037958..51e1f4b 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1856,6 +1856,9 @@
             case KeyEvent.KEYCODE_MENU:
             case KeyEvent.KEYCODE_WAKEUP:
             case KeyEvent.KEYCODE_PAIRING:
+            case KeyEvent.KEYCODE_STEM_1:
+            case KeyEvent.KEYCODE_STEM_2:
+            case KeyEvent.KEYCODE_STEM_3:
                 return true;
         }
         return false;
diff --git a/core/java/android/view/KeyboardShortcutGroup.java b/core/java/android/view/KeyboardShortcutGroup.java
new file mode 100644
index 0000000..013255b
--- /dev/null
+++ b/core/java/android/view/KeyboardShortcutGroup.java
@@ -0,0 +1,102 @@
+/*
+ * 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.view;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+/**
+ * A group of {@link KeyboardShortcutInfo}.
+ */
+public final class KeyboardShortcutGroup implements Parcelable {
+    private final CharSequence mLabel;
+    private final List<KeyboardShortcutInfo> mItems;
+
+    /**
+     * @param label The title to be used for this group, or null if there is none.
+     * @param items The set of items to be included.
+     */
+    public KeyboardShortcutGroup(@Nullable CharSequence label,
+            @NonNull List<KeyboardShortcutInfo> items) {
+        mLabel = label;
+        mItems = new ArrayList<>(checkNotNull(items));
+    }
+
+    /**
+     * @param label The title to be used for this group, or null if there is none.
+     */
+    public KeyboardShortcutGroup(@Nullable CharSequence label) {
+        this(label, Collections.<KeyboardShortcutInfo>emptyList());
+    }
+
+    private KeyboardShortcutGroup(Parcel source) {
+        mItems = new ArrayList<>();
+        mLabel = source.readCharSequence();
+        source.readTypedList(mItems, KeyboardShortcutInfo.CREATOR);
+    }
+
+    /**
+     * Returns the label to be used to describe this group.
+     */
+    public CharSequence getLabel() {
+        return mLabel;
+    }
+
+    /**
+     * Returns the list of items included in this group.
+     */
+    public List<KeyboardShortcutInfo> getItems() {
+        return mItems;
+    }
+
+    /**
+     * Adds an item to the existing list.
+     *
+     * @param item The item to be added.
+     */
+    public void addItem(KeyboardShortcutInfo item) {
+        mItems.add(item);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeCharSequence(mLabel);
+        dest.writeTypedList(mItems);
+    }
+
+    public static final Creator<KeyboardShortcutGroup> CREATOR =
+            new Creator<KeyboardShortcutGroup>() {
+        public KeyboardShortcutGroup createFromParcel(Parcel source) {
+            return new KeyboardShortcutGroup(source);
+        }
+        public KeyboardShortcutGroup[] newArray(int size) {
+            return new KeyboardShortcutGroup[size];
+        }
+    };
+}
\ No newline at end of file
diff --git a/core/java/android/view/KeyboardShortcutInfo.java b/core/java/android/view/KeyboardShortcutInfo.java
new file mode 100644
index 0000000..2c9006d
--- /dev/null
+++ b/core/java/android/view/KeyboardShortcutInfo.java
@@ -0,0 +1,134 @@
+/*
+ * 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.view;
+
+import android.annotation.Nullable;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+import static java.lang.Character.MIN_VALUE;
+
+/**
+ * Information about a Keyboard Shortcut.
+ */
+public final class KeyboardShortcutInfo implements Parcelable {
+    private final CharSequence mLabel;
+    private final Icon mIcon;
+    private final char mBaseCharacter;
+    private final int mModifiers;
+
+    /**
+     * @param label The label that identifies the action performed by this shortcut.
+     * @param icon An icon that identifies the action performed by this shortcut.
+     * @param baseCharacter The character that triggers the shortcut.
+     * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
+     *     These should be a combination of {@link KeyEvent#META_CTRL_ON},
+     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON} and
+     *     {@link KeyEvent#META_ALT_ON}.
+     *
+     * @hide
+     */
+    public KeyboardShortcutInfo(
+            @Nullable CharSequence label, @Nullable Icon icon, char baseCharacter, int modifiers) {
+        mLabel = label;
+        mIcon = icon;
+        checkArgument(baseCharacter != MIN_VALUE);
+        mBaseCharacter = baseCharacter;
+        mModifiers = modifiers;
+    }
+
+    /**
+     * Convenience constructor for shortcuts with a label and no icon.
+     *
+     * @param label The label that identifies the action performed by this shortcut.
+     * @param baseCharacter The character that triggers the shortcut.
+     * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
+     *     These should be a combination of {@link KeyEvent#META_CTRL_ON},
+     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON} and
+     *     {@link KeyEvent#META_ALT_ON}.
+     */
+    public KeyboardShortcutInfo(CharSequence label, char baseCharacter, int modifiers) {
+        mLabel = label;
+        checkArgument(baseCharacter != MIN_VALUE);
+        mBaseCharacter = baseCharacter;
+        mModifiers = modifiers;
+        mIcon = null;
+    }
+
+    private KeyboardShortcutInfo(Parcel source) {
+        mLabel = source.readCharSequence();
+        mIcon = (Icon) source.readParcelable(null);
+        mBaseCharacter = (char) source.readInt();
+        mModifiers = source.readInt();
+    }
+
+    /**
+     * Returns the label to be used to describe this shortcut.
+     */
+    @Nullable
+    public CharSequence getLabel() {
+        return mLabel;
+    }
+
+    /**
+     * Returns the icon to be used to describe this shortcut.
+     *
+     * @hide
+     */
+    @Nullable
+    public Icon getIcon() {
+        return mIcon;
+    }
+
+    /**
+     * Returns the base character that, combined with the modifiers, triggers this shortcut.
+     */
+    public char getBaseCharacter() {
+        return mBaseCharacter;
+    }
+
+    /**
+     * Returns the set of modifiers that, combined with the key, trigger this shortcut.
+     */
+    public int getModifiers() {
+        return mModifiers;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeCharSequence(mLabel);
+        dest.writeParcelable(mIcon, 0);
+        dest.writeInt(mBaseCharacter);
+        dest.writeInt(mModifiers);
+    }
+
+    public static final Creator<KeyboardShortcutInfo> CREATOR =
+            new Creator<KeyboardShortcutInfo>() {
+        public KeyboardShortcutInfo createFromParcel(Parcel source) {
+            return new KeyboardShortcutInfo(source);
+        }
+        public KeyboardShortcutInfo[] newArray(int size) {
+            return new KeyboardShortcutInfo[size];
+        }
+    };
+}
\ No newline at end of file
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index f4fa980..9f6d3e5 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -107,6 +107,7 @@
     final Rect mContentInsets = new Rect();
     final Rect mStableInsets = new Rect();
     final Rect mOutsets = new Rect();
+    final Rect mBackdropFrame = new Rect();
     final Configuration mConfiguration = new Configuration();
 
     static final int KEEP_SCREEN_ON_MSG = 1;
@@ -498,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();
@@ -529,8 +531,8 @@
                             visible ? VISIBLE : GONE,
                             WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
                             mWinFrame, mOverscanInsets, mContentInsets,
-                            mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
-                            mNewSurface);
+                            mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
+                            mConfiguration, mNewSurface);
                     if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
                         reportDrawNeeded = true;
                     }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 68f1ac3..b5b0baa 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -79,10 +79,11 @@
 import android.util.SuperNotCalledException;
 import android.util.TypedValue;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.AccessibilityIterators.TextSegmentIterator;
 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
-import android.view.AccessibilityIterators.WordTextSegmentIterator;
 import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
+import android.view.AccessibilityIterators.TextSegmentIterator;
+import android.view.AccessibilityIterators.WordTextSegmentIterator;
+import android.view.ViewGroup.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -3592,9 +3593,6 @@
 
     private int[] mDrawableState = null;
 
-    /** Whether draw() is currently being called. */
-    private boolean mInDraw = false;
-
     ViewOutlineProvider mOutlineProvider = ViewOutlineProvider.BACKGROUND;
 
     /**
@@ -6693,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) {
@@ -16473,8 +16533,6 @@
      */
     @CallSuper
     public void draw(Canvas canvas) {
-        mInDraw = true;
-
         final int privateFlags = mPrivateFlags;
         final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
                 (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
@@ -16519,7 +16577,6 @@
             onDrawForeground(canvas);
 
             // we're done...
-            mInDraw = false;
             return;
         }
 
@@ -16667,8 +16724,6 @@
 
         // Step 6, draw decorations (foreground, scrollbars)
         onDrawForeground(canvas);
-
-        mInDraw = false;
     }
 
     /**
@@ -17113,8 +17168,7 @@
      */
     @Override
     public void invalidateDrawable(@NonNull Drawable drawable) {
-        // Don't invalidate if a drawable changes during drawing.
-        if (verifyDrawable(drawable) && !mInDraw) {
+        if (verifyDrawable(drawable)) {
             final Rect dirty = drawable.getDirtyBounds();
             final int scrollX = mScrollX;
             final int scrollY = mScrollY;
@@ -17267,8 +17321,10 @@
      */
     @CallSuper
     protected boolean verifyDrawable(Drawable who) {
-        return who == mBackground || (mScrollCache != null && mScrollCache.scrollBar == who)
-                || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
+        // Avoid verifying the scroll bar drawable so that we don't end up in
+        // an invalidation loop. This effectively prevents the scroll bar
+        // drawable from triggering invalidations and scheduling runnables.
+        return who == mBackground || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
     }
 
     /**
@@ -21715,6 +21771,13 @@
     }
 
     /**
+     * @hide
+     */
+    public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> data) {
+        // Do nothing.
+    }
+
+    /**
      * Interface definition for a callback to be invoked when a hardware key event is
      * dispatched to this view. The callback will be invoked before the key event is
      * given to the view. This is only useful for hardware keyboards; a software input
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 3bea9a5..1bb0311 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -17,6 +17,10 @@
 package android.view;
 
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
 
 import android.Manifest;
 import android.animation.LayoutTransition;
@@ -79,6 +83,7 @@
 import android.widget.Scroller;
 
 import com.android.internal.R;
+import com.android.internal.os.IResultReceiver;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.policy.PhoneFallbackEventHandler;
 import com.android.internal.view.BaseSurfaceHolder;
@@ -140,6 +145,9 @@
      */
     static final int MAX_TRACKBALL_DELAY = 250;
 
+    private static final int RESIZE_MODE_FREEFORM = 0;
+    private static final int RESIZE_MODE_DOCKED_DIVIDER = 1;
+
     static final ThreadLocal<HandlerActionQueue> sRunQueues = new ThreadLocal<HandlerActionQueue>();
 
     static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList();
@@ -224,8 +232,10 @@
     boolean mIsAnimating;
 
     private boolean mDragResizing;
+    private int mResizeMode;
     private int mCanvasOffsetX;
     private int mCanvasOffsetY;
+    private boolean mActivityRelaunched;
 
     CompatibilityInfo.Translator mTranslator;
 
@@ -1241,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 {
@@ -1336,6 +1349,17 @@
         host.dispatchApplyWindowInsets(getWindowInsets(true /* forceConstruct */));
     }
 
+    private static boolean shouldUseDisplaySize(final WindowManager.LayoutParams lp) {
+        return lp.type == TYPE_STATUS_BAR_PANEL
+                || lp.type == TYPE_INPUT_METHOD
+                || lp.type == TYPE_VOLUME_OVERLAY;
+    }
+
+    private int dipToPx(int dip) {
+        final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+        return (int) (displayMetrics.density * dip + 0.5f);
+    }
+
     private void performTraversals() {
         // cache mView since it is used so much below...
         final View host = mView;
@@ -1390,18 +1414,16 @@
             mFullRedrawNeeded = true;
             mLayoutRequested = true;
 
-            if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL
-                    || lp.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD) {
+            if (shouldUseDisplaySize(lp)) {
                 // NOTE -- system code, won't try to do compat mode.
                 Point size = new Point();
                 mDisplay.getRealSize(size);
                 desiredWindowWidth = size.x;
                 desiredWindowHeight = size.y;
             } else {
-                DisplayMetrics packageMetrics =
-                    mView.getContext().getResources().getDisplayMetrics();
-                desiredWindowWidth = packageMetrics.widthPixels;
-                desiredWindowHeight = packageMetrics.heightPixels;
+                Configuration config = mContext.getResources().getConfiguration();
+                desiredWindowWidth = dipToPx(config.screenWidthDp);
+                desiredWindowHeight = dipToPx(config.screenHeightDp);
             }
 
             // We used to use the following condition to choose 32 bits drawing caches:
@@ -1485,17 +1507,21 @@
                 if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) {
                     insetsChanged = true;
                 }
-                if ((lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
-                        || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT)
-                        && (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL
-                                || lp.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD
-                                || lp.type == WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)) {
+                if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
+                        || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                     windowSizeMayChange = true;
-                    // NOTE -- system code, won't try to do compat mode.
-                    Point size = new Point();
-                    mDisplay.getRealSize(size);
-                    desiredWindowWidth = size.x;
-                    desiredWindowHeight = size.y;
+
+                    if (shouldUseDisplaySize(lp)) {
+                        // NOTE -- system code, won't try to do compat mode.
+                        Point size = new Point();
+                        mDisplay.getRealSize(size);
+                        desiredWindowWidth = size.x;
+                        desiredWindowHeight = size.y;
+                    } else {
+                        Configuration config = res.getConfiguration();
+                        desiredWindowWidth = dipToPx(config.screenWidthDp);
+                        desiredWindowHeight = dipToPx(config.screenHeightDp);
+                    }
                 }
             }
 
@@ -1575,12 +1601,17 @@
                         frame.width() < desiredWindowWidth && frame.width() != mWidth)
                 || (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT &&
                         frame.height() < desiredWindowHeight && frame.height() != mHeight));
-        windowShouldResize |= mDragResizing;
+        windowShouldResize |= mDragResizing && mResizeMode == RESIZE_MODE_FREEFORM;
 
         // If the backdrop frame doesn't equal to a frame, we are starting a resize operation, so
         // force it to be resized.
         windowShouldResize |= !mPendingBackDropFrame.equals(mWinFrame);
 
+        // If the activity was just relaunched, it might have unfrozen the task bounds (while
+        // relaunching), so we need to force a call into window manager to pick up the latest
+        // bounds.
+        windowShouldResize |= mActivityRelaunched;
+
         // Determine whether to compute insets.
         // If there are no inset listeners remaining then we may still need to compute
         // insets in case the old insets were non-empty and must be reset.
@@ -1769,11 +1800,17 @@
                     }
                 }
 
-                final boolean dragResizing = (relayoutResult
-                        & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING) != 0;
+                final boolean freeformResizing = (relayoutResult
+                        & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM) != 0;
+                final boolean dockedResizing = (relayoutResult
+                        & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED) != 0;
+                final boolean dragResizing = freeformResizing || dockedResizing;
                 if (mDragResizing != dragResizing) {
                     if (dragResizing) {
                         startDragResizing(mPendingBackDropFrame);
+                        mResizeMode = freeformResizing
+                                ? RESIZE_MODE_FREEFORM
+                                : RESIZE_MODE_DOCKED_DIVIDER;
                     } else {
                         // We shouldn't come here, but if we come we should end the resize.
                         endDragResizing();
@@ -1920,29 +1957,7 @@
             // in the attach info. We translate only the window frame since on window move
             // the window manager tells us only for the new frame but the insets are the
             // same and we do not want to translate them more than once.
-
-            // TODO: Well, we are checking whether the frame has changed similarly
-            // to how this is done for the insets. This is however incorrect since
-            // the insets and the frame are translated. For example, the old frame
-            // was (1, 1 - 1, 1) and was translated to say (2, 2 - 2, 2), now the new
-            // reported frame is (2, 2 - 2, 2) which implies no change but this is not
-            // true since we are comparing a not translated value to a translated one.
-            // This scenario is rare but we may want to fix that.
-
-            final boolean windowMoved = (mAttachInfo.mWindowLeft != frame.left
-                    || mAttachInfo.mWindowTop != frame.top);
-            if (windowMoved) {
-                if (mTranslator != null) {
-                    mTranslator.translateRectInScreenToAppWinFrame(frame);
-                }
-                mAttachInfo.mWindowLeft = frame.left;
-                mAttachInfo.mWindowTop = frame.top;
-
-                // Update the light position for the new window offsets.
-                if (mAttachInfo.mHardwareRenderer != null) {
-                    mAttachInfo.mHardwareRenderer.setLightCenter(mAttachInfo);
-                }
-            }
+            maybeHandleWindowMove(frame);
         }
 
         final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
@@ -2057,6 +2072,7 @@
         mFirst = false;
         mWillDrawSoon = false;
         mNewSurfaceNeeded = false;
+        mActivityRelaunched = false;
         mViewVisibility = viewVisibility;
         mHadWindowFocus = hasWindowFocus;
 
@@ -2106,6 +2122,31 @@
         mIsInTraversal = false;
     }
 
+    private void maybeHandleWindowMove(Rect frame) {
+
+        // TODO: Well, we are checking whether the frame has changed similarly
+        // to how this is done for the insets. This is however incorrect since
+        // the insets and the frame are translated. For example, the old frame
+        // was (1, 1 - 1, 1) and was translated to say (2, 2 - 2, 2), now the new
+        // reported frame is (2, 2 - 2, 2) which implies no change but this is not
+        // true since we are comparing a not translated value to a translated one.
+        // This scenario is rare but we may want to fix that.
+
+        final boolean windowMoved = mAttachInfo.mWindowLeft != frame.left
+                || mAttachInfo.mWindowTop != frame.top;
+        if (windowMoved) {
+            if (mTranslator != null) {
+                mTranslator.translateRectInScreenToAppWinFrame(frame);
+            }
+            mAttachInfo.mWindowLeft = frame.left;
+            mAttachInfo.mWindowTop = frame.top;
+
+            // Update the light position for the new window offsets.
+            if (mAttachInfo.mHardwareRenderer != null) {
+                mAttachInfo.mHardwareRenderer.setLightCenter(mAttachInfo);
+            }
+        }
+    }
     private void handleOutOfResourcesException(Surface.OutOfResourcesException e) {
         Log.e(mTag, "OutOfResourcesException initializing HW surface", e);
         try {
@@ -3235,6 +3276,7 @@
     private final static int MSG_WINDOW_MOVED = 23;
     private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24;
     private final static int MSG_DISPATCH_WINDOW_SHOWN = 25;
+    private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -3366,10 +3408,19 @@
 
                     mPendingBackDropFrame.set(mWinFrame);
 
-                    if (mView != null) {
-                        forceLayout(mView);
+                    // Suppress layouts during resizing - a correct layout will happen when resizing
+                    // is done, and this just increases system load.
+                    boolean isDockedDivider = mWindowAttributes.type == TYPE_DOCK_DIVIDER;
+                    boolean suppress = (mDragResizing && mResizeMode == RESIZE_MODE_DOCKED_DIVIDER)
+                            || isDockedDivider;
+                    if (!suppress) {
+                        if (mView != null) {
+                            forceLayout(mView);
+                        }
+                        requestLayout();
+                    } else {
+                        maybeHandleWindowMove(mWinFrame);
                     }
-                    requestLayout();
                 }
                 break;
             case MSG_WINDOW_FOCUS_CHANGED: {
@@ -3511,7 +3562,11 @@
             } break;
             case MSG_DISPATCH_WINDOW_SHOWN: {
                 handleDispatchWindowShown();
-            }
+            } break;
+            case MSG_REQUEST_KEYBOARD_SHORTCUTS: {
+                IResultReceiver receiver = (IResultReceiver) msg.obj;
+                handleRequestKeyboardShortcuts(receiver);
+            } break;
             }
         }
     }
@@ -5402,6 +5457,19 @@
         mAttachInfo.mTreeObserver.dispatchOnWindowShown();
     }
 
+    public void handleRequestKeyboardShortcuts(IResultReceiver receiver) {
+        Bundle data = new Bundle();
+        ArrayList<KeyboardShortcutGroup> list = new ArrayList<>();
+        if (mView != null) {
+            mView.requestKeyboardShortcuts(list);
+        }
+        data.putParcelableArrayList(WindowManager.PARCEL_KEY_SHORTCUTS_ARRAY, list);
+        try {
+            receiver.send(0, data);
+        } catch (RemoteException e) {
+        }
+    }
+
     public void getLastTouchPoint(Point outLocation) {
         outLocation.x = (int) mLastTouchPoint.x;
         outLocation.y = (int) mLastTouchPoint.y;
@@ -5463,7 +5531,8 @@
                 (int) (mView.getMeasuredHeight() * appScale + 0.5f),
                 viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
                 mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
-                mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface);
+                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration,
+                mSurface);
         //Log.d(mTag, "<<<<<< BACK FROM relayout");
         if (restore) {
             params.restore();
@@ -6331,6 +6400,10 @@
         }
     }
 
+    public void dispatchRequestKeyboardShortcuts(IResultReceiver receiver) {
+        mHandler.obtainMessage(MSG_REQUEST_KEYBOARD_SHORTCUTS, receiver).sendToTarget();
+    }
+
     /**
      * Post a callback to send a
      * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} event.
@@ -6904,6 +6977,14 @@
                 viewAncestor.dispatchWindowShown();
             }
         }
+
+        @Override
+        public void requestAppKeyboardShortcuts(IResultReceiver receiver) {
+          ViewRootImpl viewAncestor = mViewAncestor.get();
+          if (viewAncestor != null) {
+            viewAncestor.dispatchRequestKeyboardShortcuts(receiver);
+          }
+        }
     }
 
     public static final class CalledFromWrongThreadException extends AndroidRuntimeException {
@@ -6977,6 +7058,15 @@
     }
 
     /**
+     * Tells this instance that its corresponding activity has just relaunched. In this case, we
+     * need to force a relayout of the window to make sure we get the correct bounds from window
+     * manager.
+     */
+    public void reportActivityRelaunched() {
+        mActivityRelaunched = true;
+    }
+
+    /**
      * Class for managing the accessibility interaction connection
      * based on the global accessibility state.
      */
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 0b06d15..dfe0cc7 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -42,6 +42,8 @@
 import android.transition.TransitionManager;
 import android.view.accessibility.AccessibilityEvent;
 
+import java.util.List;
+
 /**
  * Abstract base class for a top-level window look and behavior policy.  An
  * instance of this class should be used as the top-level view added to the
@@ -556,6 +558,15 @@
          * @param mode The mode that was just finished.
          */
         public void onActionModeFinished(ActionMode mode);
+
+        /**
+         * Called when Keyboard Shortcuts are requested for the current window.
+         *
+         * @param data The data list to populate with shortcuts.
+         * @param menu The current menu, which may be null.
+         */
+        public void onProvideKeyboardShortcuts(
+                List<KeyboardShortcutGroup> data, @Nullable Menu menu);
     }
 
     /** @hide */
@@ -2109,4 +2120,10 @@
      * @hide
      */
     public abstract void onMultiWindowModeChanged();
+
+    /**
+     * Called when the activity just relaunched.
+     * @hide
+     */
+    public abstract void reportActivityRelaunched();
 }
diff --git a/core/java/android/view/WindowCallbackWrapper.java b/core/java/android/view/WindowCallbackWrapper.java
index 8ce1f8c..bed74e9 100644
--- a/core/java/android/view/WindowCallbackWrapper.java
+++ b/core/java/android/view/WindowCallbackWrapper.java
@@ -19,6 +19,8 @@
 
 import android.view.accessibility.AccessibilityEvent;
 
+import java.util.List;
+
 /**
  * A simple decorator stub for Window.Callback that passes through any calls
  * to the wrapped instance as a base implementation. Call super.foo() to call into
@@ -150,5 +152,10 @@
     public void onActionModeFinished(ActionMode mode) {
         mWrapped.onActionModeFinished(mode);
     }
+
+    @Override
+    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
+        mWrapped.onProvideKeyboardShortcuts(data, menu);
+    }
 }
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 251f4c8..772eeec 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -29,6 +29,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import java.util.List;
+
 
 /**
  * The interface that apps use to talk to the window manager.
@@ -118,6 +120,34 @@
      */
     public void removeViewImmediate(View view);
 
+    /**
+     * Used to asynchronously request Keyboard Shortcuts from the focused window.
+     *
+     * @hide
+     */
+    public interface KeyboardShortcutsReceiver {
+        /**
+         * Callback used when the focused window keyboard shortcuts are ready to be displayed.
+         *
+         * @param result The keyboard shortcuts to be displayed.
+         */
+        void onKeyboardShortcutsReceived(List<KeyboardShortcutGroup> result);
+    }
+
+    /**
+     * @hide
+     */
+    public static final String PARCEL_KEY_SHORTCUTS_ARRAY = "shortcuts_array";
+
+    /**
+     * Request for keyboard shortcuts to be retrieved asynchronously.
+     *
+     * @param receiver The callback to be triggered when the result is ready.
+     *
+     * @hide
+     */
+    public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver);
+
     public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
         /**
          * X position for this window.  With the default gravity it is ignored.
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 8c68e92..1530b47 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -30,6 +30,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.view.inputmethod.InputMethodManager;
+
 import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
@@ -70,16 +71,23 @@
     public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
 
     /**
+     * The window is being resized by dragging on the docked divider. The client should render
+     * at (0, 0) and extend its background to the background frame passed into
+     * {@link IWindow#resized}.
+     */
+    public static final int RELAYOUT_RES_DRAG_RESIZING_DOCKED = 0x8;
+
+    /**
      * The window is being resized by dragging one of the window corners,
      * in this case the surface would be fullscreen-sized. The client should
      * render to the actual frame location (instead of (0,curScrollY)).
      */
-    public static final int RELAYOUT_RES_DRAG_RESIZING = 0x8;
+    public static final int RELAYOUT_RES_DRAG_RESIZING_FREEFORM = 0x10;
 
     /**
      * The window manager has changed the size of the surface from the last call.
      */
-    public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x10;
+    public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x20;
 
     /**
      * Flag for relayout: the client will be later giving
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 98e9f54..6e11671 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -17,7 +17,15 @@
 package android.view;
 
 import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Bundle;
 import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.internal.os.IResultReceiver;
+import com.android.internal.R;
+
+import java.util.List;
 
 /**
  * Provides low-level communication with the system window manager for
@@ -117,6 +125,23 @@
     }
 
     @Override
+    public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver) {
+        IResultReceiver resultReceiver = new IResultReceiver.Stub() {
+            @Override
+            public void send(int resultCode, Bundle resultData) throws RemoteException {
+                List<KeyboardShortcutGroup> result =
+                        resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY);
+                receiver.onKeyboardShortcutsReceived(result);
+            }
+        };
+        try {
+            WindowManagerGlobal.getWindowManagerService()
+                .requestAppKeyboardShortcuts(resultReceiver);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @Override
     public Display getDefaultDisplay() {
         return mDisplay;
     }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index a78b56a..4a1142f 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1333,9 +1333,9 @@
      * Calculates the stable insets without running a layout.
      *
      * @param displayRotation the current display rotation
-     * @param outInsets the insets to return
      * @param displayWidth the current display width
      * @param displayHeight the current display height
+     * @param outInsets the insets to return
      */
     public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
             Rect outInsets);
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/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index b6570cc..9e79057 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -58,5 +58,5 @@
     void temporaryEnableAccessibilityStateUntilKeyguardRemoved(in ComponentName service,
             boolean touchExplorationEnabled);
 
-    IBinder getWindowToken(int windowId);
+    IBinder getWindowToken(int windowId, int userId);
 }
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index e0dbe2f..1536c29 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -850,7 +850,7 @@
             normalizedTime = currentTime < mStartTime ? 0.0f : 1.0f;
         }
 
-        final boolean expired = normalizedTime >= 1.0f;
+        final boolean expired = normalizedTime >= 1.0f || isCanceled();
         mMore = !expired;
 
         if (!mFillEnabled) normalizedTime = Math.max(Math.min(normalizedTime, 1.0f), 0.0f);
@@ -875,7 +875,7 @@
         }
 
         if (expired) {
-            if (mRepeatCount == mRepeated) {
+            if (mRepeatCount == mRepeated || isCanceled()) {
                 if (!mEnded) {
                     mEnded = true;
                     guard.close();
@@ -905,6 +905,10 @@
         return mMore;
     }
 
+    private boolean isCanceled() {
+        return mStartTime == Long.MIN_VALUE;
+    }
+
     private void fireAnimationStart() {
         if (mListener != null) {
             if (mListenerHandler == null) mListener.onAnimationStart(this);
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 6e5e591..a10f792 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -195,7 +195,6 @@
     public boolean commitText(CharSequence text, int newCursorPosition) {
         if (DEBUG) Log.v(TAG, "commitText " + text);
         replaceText(text, newCursorPosition, false);
-        mIMM.notifyUserAction();
         sendCurrentText();
         return true;
     }
@@ -230,7 +229,7 @@
             b = tmp;
         }
 
-        // ignore the composing text.
+        // Ignore the composing text.
         int ca = getComposingSpanStart(content);
         int cb = getComposingSpanEnd(content);
         if (cb < ca) {
@@ -266,6 +265,167 @@
         return true;
     }
 
+    private static int INVALID_INDEX = -1;
+    private static int findIndexBackward(final CharSequence cs, final int from,
+            final int numCodePoints) {
+        int currentIndex = from;
+        boolean waitingHighSurrogate = false;
+        final int N = cs.length();
+        if (currentIndex < 0 || N < currentIndex) {
+            return INVALID_INDEX;  // The starting point is out of range.
+        }
+        if (numCodePoints < 0) {
+            return INVALID_INDEX;  // Basically this should not happen.
+        }
+        int remainingCodePoints = numCodePoints;
+        while (true) {
+            if (remainingCodePoints == 0) {
+                return currentIndex;  // Reached to the requested length in code points.
+            }
+
+            --currentIndex;
+            if (currentIndex < 0) {
+                if (waitingHighSurrogate) {
+                    return INVALID_INDEX;  // An invalid surrogate pair is found.
+                }
+                return 0;  // Reached to the beginning of the text w/o any invalid surrogate pair.
+            }
+            final char c = cs.charAt(currentIndex);
+            if (waitingHighSurrogate) {
+                if (!java.lang.Character.isHighSurrogate(c)) {
+                    return INVALID_INDEX;  // An invalid surrogate pair is found.
+                }
+                waitingHighSurrogate = false;
+                --remainingCodePoints;
+                continue;
+            }
+            if (!java.lang.Character.isSurrogate(c)) {
+                --remainingCodePoints;
+                continue;
+            }
+            if (java.lang.Character.isHighSurrogate(c)) {
+                return INVALID_INDEX;  // A invalid surrogate pair is found.
+            }
+            waitingHighSurrogate = true;
+        }
+    }
+
+    private static int findIndexForward(final CharSequence cs, final int from,
+            final int numCodePoints) {
+        int currentIndex = from;
+        boolean waitingLowSurrogate = false;
+        final int N = cs.length();
+        if (currentIndex < 0 || N < currentIndex) {
+            return INVALID_INDEX;  // The starting point is out of range.
+        }
+        if (numCodePoints < 0) {
+            return INVALID_INDEX;  // Basically this should not happen.
+        }
+        int remainingCodePoints = numCodePoints;
+
+        while (true) {
+            if (remainingCodePoints == 0) {
+                return currentIndex;  // Reached to the requested length in code points.
+            }
+
+            if (currentIndex >= N) {
+                if (waitingLowSurrogate) {
+                    return INVALID_INDEX;  // An invalid surrogate pair is found.
+                }
+                return N;  // Reached to the end of the text w/o any invalid surrogate pair.
+            }
+            final char c = cs.charAt(currentIndex);
+            if (waitingLowSurrogate) {
+                if (!java.lang.Character.isLowSurrogate(c)) {
+                    return INVALID_INDEX;  // An invalid surrogate pair is found.
+                }
+                --remainingCodePoints;
+                waitingLowSurrogate = false;
+                ++currentIndex;
+                continue;
+            }
+            if (!java.lang.Character.isSurrogate(c)) {
+                --remainingCodePoints;
+                ++currentIndex;
+                continue;
+            }
+            if (java.lang.Character.isLowSurrogate(c)) {
+                return INVALID_INDEX;  // A invalid surrogate pair is found.
+            }
+            waitingLowSurrogate = true;
+            ++currentIndex;
+        }
+    }
+
+    /**
+     * The default implementation performs the deletion around the current selection position of the
+     * editable text.
+     * @param beforeLength The number of characters before the cursor to be deleted, in code points.
+     *        If this is greater than the number of existing characters between the beginning of the
+     *        text and the cursor, then this method does not fail but deletes all the characters in
+     *        that range.
+     * @param afterLength The number of characters after the cursor to be deleted, in code points.
+     *        If this is greater than the number of existing characters between the cursor and
+     *        the end of the text, then this method does not fail but deletes all the characters in
+     *        that range.
+     */
+    public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
+        if (DEBUG) Log.v(TAG, "deleteSurroundingText " + beforeLength
+                + " / " + afterLength);
+        final Editable content = getEditable();
+        if (content == null) return false;
+
+        beginBatchEdit();
+
+        int a = Selection.getSelectionStart(content);
+        int b = Selection.getSelectionEnd(content);
+
+        if (a > b) {
+            int tmp = a;
+            a = b;
+            b = tmp;
+        }
+
+        // Ignore the composing text.
+        int ca = getComposingSpanStart(content);
+        int cb = getComposingSpanEnd(content);
+        if (cb < ca) {
+            int tmp = ca;
+            ca = cb;
+            cb = tmp;
+        }
+        if (ca != -1 && cb != -1) {
+            if (ca < a) a = ca;
+            if (cb > b) b = cb;
+        }
+
+        if (a >= 0 && b >= 0) {
+            final int start = findIndexBackward(content, a, Math.max(beforeLength, 0));
+            if (start != INVALID_INDEX) {
+                final int end = findIndexForward(content, b, Math.max(afterLength, 0));
+                if (end != INVALID_INDEX) {
+                    final int numDeleteBefore = a - start;
+                    if (numDeleteBefore > 0) {
+                        content.delete(start, a);
+                    }
+                    final int numDeleteAfter = end - b;
+                    if (numDeleteAfter > 0) {
+                        content.delete(b - numDeleteBefore, end - numDeleteBefore);
+                    }
+                }
+            }
+            // NOTE: You may think we should return false here if start and/or end is INVALID_INDEX,
+            // but the truth is that IInputConnectionWrapper running in the middle of IPC calls
+            // always returns true to the IME without waiting for the completion of this method as
+            // IInputConnectionWrapper#isAtive() returns true.  This is actually why some methods
+            // including this method look like asynchronous calls from the IME.
+        }
+
+        endBatchEdit();
+
+        return true;
+    }
+
     /**
      * The default implementation removes the composing state from the
      * current editable text.  In addition, only if dummy mode, a key event is
@@ -450,7 +610,6 @@
     public boolean setComposingText(CharSequence text, int newCursorPosition) {
         if (DEBUG) Log.v(TAG, "setComposingText " + text);
         replaceText(text, newCursorPosition, true);
-        mIMM.notifyUserAction();
         return true;
     }
 
@@ -523,29 +682,17 @@
      * attached to the input connection's view.
      */
     public boolean sendKeyEvent(KeyEvent event) {
-        synchronized (mIMM.mH) {
-            ViewRootImpl viewRootImpl = mTargetView != null ? mTargetView.getViewRootImpl() : null;
-            if (viewRootImpl == null) {
-                if (mIMM.mServedView != null) {
-                    viewRootImpl = mIMM.mServedView.getViewRootImpl();
-                }
-            }
-            if (viewRootImpl != null) {
-                viewRootImpl.dispatchKeyFromIme(event);
-            }
-        }
-        mIMM.notifyUserAction();
+        mIMM.dispatchKeyEventFromInputMethod(mTargetView, event);
         return false;
     }
-    
+
     /**
      * Updates InputMethodManager with the current fullscreen mode.
      */
     public boolean reportFullscreenMode(boolean enabled) {
-        mIMM.setFullscreenMode(enabled);
         return true;
     }
-    
+
     private void sendCurrentText() {
         if (!mDummyMode) {
             return;
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index be7bc14..eb773e2 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -348,6 +348,33 @@
     public boolean deleteSurroundingText(int beforeLength, int afterLength);
 
     /**
+     * A variant of {@link #deleteSurroundingText(int, int)}. Major differences are:
+     *
+     * <ul>
+     *     <li>The lengths are supplied in code points, not in Java chars or in glyphs.</>
+     *     <li>This method does nothing if there are one or more invalid surrogate pairs in the
+     *     requested range.</li>
+     * </ul>
+     *
+     * <p><strong>Editor authors:</strong> In addition to the requirement in
+     * {@link #deleteSurroundingText(int, int)}, make sure to do nothing when one ore more invalid
+     * surrogate pairs are found in the requested range.</p>
+     *
+     * @see #deleteSurroundingText(int, int)
+     *
+     * @param beforeLength The number of characters before the cursor to be deleted, in code points.
+     *        If this is greater than the number of existing characters between the beginning of the
+     *        text and the cursor, then this method does not fail but deletes all the characters in
+     *        that range.
+     * @param afterLength The number of characters after the cursor to be deleted, in code points.
+     *        If this is greater than the number of existing characters between the cursor and
+     *        the end of the text, then this method does not fail but deletes all the characters in
+     *        that range.
+     * @return true on success, false if the input connection is no longer valid.
+     */
+    public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength);
+
+    /**
      * Replace the currently composing text with the given text, and
      * set the new cursor position. Any composing text set previously
      * will be removed automatically.
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index 231aa07..e5ae422 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -62,6 +62,10 @@
         return mTarget.getExtractedText(request, flags);
     }
 
+    public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
+        return mTarget.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
+    }
+
     public boolean deleteSurroundingText(int beforeLength, int afterLength) {
         return mTarget.deleteSurroundingText(beforeLength, afterLength);
     }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 5e07347..0ed2299 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -25,6 +25,8 @@
 import com.android.internal.view.InputBindResult;
 import com.android.internal.view.InputMethodClient;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.graphics.Rect;
@@ -527,7 +529,7 @@
             }
         }
     }
-    
+
     private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
         private final InputMethodManager mParentInputMethodManager;
         private boolean mActive;
@@ -549,13 +551,23 @@
         }
 
         @Override
+        protected void onUserAction() {
+            mParentInputMethodManager.notifyUserAction();
+        }
+
+        @Override
+        protected void onReportFullscreenMode(boolean enabled) {
+            mParentInputMethodManager.setFullscreenMode(enabled);
+        }
+
+        @Override
         public String toString() {
             return "ControlledInputConnectionWrapper{mActive=" + mActive
                     + " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
                     + "}";
         }
     }
-    
+
     final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() {
         @Override
         protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
@@ -1813,6 +1825,34 @@
         return DISPATCH_NOT_HANDLED;
     }
 
+    /**
+     * Provides the default implementation of {@link InputConnection#sendKeyEvent(KeyEvent)}, which
+     * is expected to dispatch an keyboard event sent from the IME to an appropriate event target
+     * depending on the given {@link View} and the current focus state.
+     *
+     * <p>CAUTION: This method is provided only for the situation where
+     * {@link InputConnection#sendKeyEvent(KeyEvent)} needs to be implemented without relying on
+     * {@link BaseInputConnection}. Do not use this API for anything else.</p>
+     *
+     * @param targetView the default target view. If {@code null} is specified, then this method
+     * tries to find a good event target based on the current focus state.
+     * @param event the key event to be dispatched.
+     */
+    public void dispatchKeyEventFromInputMethod(@Nullable View targetView,
+            @NonNull KeyEvent event) {
+        synchronized (mH) {
+            ViewRootImpl viewRootImpl = targetView != null ? targetView.getViewRootImpl() : null;
+            if (viewRootImpl == null) {
+                if (mServedView != null) {
+                    viewRootImpl = mServedView.getViewRootImpl();
+                }
+            }
+            if (viewRootImpl != null) {
+                viewRootImpl.dispatchKeyFromIme(event);
+            }
+        }
+    }
+
     // Must be called on the main looper
     void sendInputEventAndReportResultOnMainLooper(PendingEvent p) {
         final boolean handled;
@@ -2163,6 +2203,17 @@
      * by changing its extra value. The different subtype won't get affected by the stored past
      * status. (You may want to take a look at {@link InputMethodSubtype#hashCode()} to refer
      * to the current implementation.)
+     *
+     * <p>NOTE: If the same subtype exists in both the manifest XML file and additional subtypes
+     * specified by {@code subtypes}, those multiple instances are automatically merged into one
+     * instance.</p>
+     *
+     * <p>CAVEAT: In API Level 23 and prior, the system may do nothing if an empty
+     * {@link InputMethodSubtype} is specified in {@code subtypes}, which prevents you from removing
+     * the last one entry of additional subtypes. If your IME statically defines one or more
+     * subtypes in the manifest XML file, you may be able to work around this limitation by
+     * specifying one of those statically defined subtypes in {@code subtypes}.</p>
+     *
      * @param imiId Id of InputMethodInfo which additional input method subtypes will be added to.
      * @param subtypes subtypes will be added as additional subtypes of the current input method.
      */
diff --git a/core/java/android/webkit/TokenBindingService.java b/core/java/android/webkit/TokenBindingService.java
new file mode 100644
index 0000000..f11ce51
--- /dev/null
+++ b/core/java/android/webkit/TokenBindingService.java
@@ -0,0 +1,91 @@
+/*
+ * 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.webkit;
+
+import android.annotation.SystemApi;
+import android.net.Uri;
+
+import java.security.KeyPair;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * Enables the token binding procotol, and provides access to the keys. See
+ * https://tools.ietf.org/html/draft-ietf-tokbind-protocol-03
+ *
+ * All methods are required to be called on the UI thread where WebView is
+ * 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";
+    public static final String KEY_ALGORITHM_RSA2048_PSS = "RSA2048PSS";
+    public static final String KEY_ALGORITHM_ECDSAP256 = "ECDSAP256";
+
+    /**
+     * Returns the default TokenBinding service instance. At present there is
+     * only one token binding service instance for all WebView instances,
+     * however this restriction may be relaxed in the future.
+     *
+     * @return The default TokenBindingService instance.
+     */
+    public static TokenBindingService getInstance() {
+        return WebViewFactory.getProvider().getTokenBindingService();
+    }
+
+    /**
+     * Enables the token binding protocol. The token binding protocol
+     * has to be enabled before creating any WebViews.
+     *
+     * @throws IllegalStateException if a WebView was already created.
+     */
+    public abstract void enableTokenBinding();
+
+    /**
+     * Retrieves the key pair for a given origin from the internal
+     * TokenBinding key store asynchronously.
+     * Will create a key pair if one does not exist.
+     *
+     * @param origin The origin for the server.
+     * @param algorithm The algorithm for generating the token binding key.
+     * @param callback The callback that will be called when key is available.
+     *        Cannot be null.
+     */
+    public abstract void getKey(Uri origin,
+                                String algorithm,
+                                ValueCallback<KeyPair> callback);
+    /**
+     * Deletes specified key (for use when associated cookie is cleared).
+     *
+     * @param origin The origin of the server.
+     * @param callback The callback that will be called when key is deleted. The
+     *        callback parameter (Boolean) will indicate if operation is
+     *        successful or if failed. The callback can be null.
+     */
+    public abstract void deleteKey(Uri origin,
+                                   ValueCallback<Boolean> callback);
+
+     /**
+      * Deletes all the keys (for use when cookies are cleared).
+      *
+      * @param callback The callback that will be called when keys are deleted.
+      *        The callback parameter (Boolean) will indicate if operation is
+      *        successful or if failed. The callback can be null.
+      */
+    public abstract void deleteAllKeys(ValueCallback<Boolean> callback);
+}
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 9105394..2b66a83 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -103,6 +103,14 @@
     CookieManager getCookieManager();
 
     /**
+     * Gets the TokenBindingService instance for this WebView implementation. The
+     * implementation must return the same instance on subsequent calls.
+     *
+     * @return the TokenBindingService instance
+     */
+    TokenBindingService getTokenBindingService();
+
+    /**
      * Gets the singleton WebIconDatabase instance for this WebView implementation. The
      * implementation must return the same instance on subsequent calls.
      *
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e1ce9fe..6241a4c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5803,6 +5803,11 @@
         }
 
         @Override
+        public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
+            return getTarget().deleteSurroundingTextInCodePoints(beforeLength, afterLength);
+        }
+
+        @Override
         public boolean setComposingText(CharSequence text, int newCursorPosition) {
             return getTarget().setComposingText(text, newCursorPosition);
         }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 831481dd..4ca8971 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -142,6 +142,7 @@
         }
 
         applyThumbTint();
+        applyTickMarkTint();
 
         mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
     }
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index 48d1d2b..ac8d578 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -59,7 +59,6 @@
  */
 public class ActionMenuPresenter extends BaseMenuPresenter
         implements ActionProvider.SubUiVisibilityListener {
-    private static final String TAG = "ActionMenuPresenter";
     private static final int ITEM_ANIMATION_DURATION = 150;
     private static final boolean ACTIONBAR_ANIMATIONS_ENABLED = false;
 
@@ -87,20 +86,16 @@
     private OpenOverflowRunnable mPostedOpenRunnable;
     private ActionMenuPopupCallback mPopupCallback;
 
-    private final boolean mShowCascadingMenus;
-
     final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
     int mOpenSubMenuId;
 
     // These collections are used to store pre- and post-layout information for menu items,
     // which is used to determine appropriate animations to run for changed items.
-    private SparseArray<MenuItemLayoutInfo> mPreLayoutItems =
-            new SparseArray<MenuItemLayoutInfo>();
-    private SparseArray<MenuItemLayoutInfo> mPostLayoutItems =
-            new SparseArray<MenuItemLayoutInfo>();
+    private SparseArray<MenuItemLayoutInfo> mPreLayoutItems = new SparseArray<>();
+    private SparseArray<MenuItemLayoutInfo> mPostLayoutItems = new SparseArray<>();
 
     // The list of currently running animations on menu items.
-    private List<ItemAnimationInfo> mRunningItemAnimations = new ArrayList<ItemAnimationInfo>();
+    private List<ItemAnimationInfo> mRunningItemAnimations = new ArrayList<>();
     private ViewTreeObserver.OnPreDrawListener mItemAnimationPreDrawListener =
             new ViewTreeObserver.OnPreDrawListener() {
         @Override
@@ -130,9 +125,6 @@
     public ActionMenuPresenter(Context context) {
         super(context, com.android.internal.R.layout.action_menu_layout,
                 com.android.internal.R.layout.action_menu_item_layout);
-
-        mShowCascadingMenus = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_enableCascadingSubmenus);
     }
 
     @Override
@@ -845,8 +837,6 @@
     }
 
     private class OverflowMenuButton extends ImageButton implements ActionMenuView.ActionMenuChildView {
-        private final float[] mTempPts = new float[2];
-
         public OverflowMenuButton(Context context) {
             super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle);
 
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 2aaa356..cde7604 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -16,8 +16,11 @@
 
 package android.widget;
 
+import android.annotation.AttrRes;
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.StyleRes;
 import android.annotation.Widget;
 import android.content.Context;
@@ -37,9 +40,13 @@
 import java.util.TimeZone;
 
 /**
- * This class is a calendar widget for displaying and selecting dates. The range
- * of dates supported by this calendar is configurable. A user can select a date
- * by taping on it and can scroll and fling the calendar to a desired date.
+ * This class is a calendar widget for displaying and selecting dates. The
+ * range of dates supported by this calendar is configurable.
+ * <p>
+ * The exact appearance and interaction model of this widget may vary between
+ * OS versions and themes (e.g. Holo versus Material), but in general a user
+ * can select a date by tapping on it and can scroll or fling the calendar to a
+ * desired date.
  *
  * @attr ref android.R.styleable#CalendarView_showWeekNumber
  * @attr ref android.R.styleable#CalendarView_firstDayOfWeek
@@ -77,22 +84,24 @@
          * @param month The month that was set [0-11].
          * @param dayOfMonth The day of the month that was set.
          */
-        public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth);
+        void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth);
     }
 
-    public CalendarView(Context context) {
+    public CalendarView(@NonNull Context context) {
         this(context, null);
     }
 
-    public CalendarView(Context context, AttributeSet attrs) {
+    public CalendarView(@NonNull Context context, @Nullable AttributeSet attrs) {
         this(context, attrs, R.attr.calendarViewStyle);
     }
 
-    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
+    public CalendarView(@NonNull Context context, @Nullable AttributeSet attrs,
+            @AttrRes int defStyleAttr) {
         this(context, attrs, defStyleAttr, 0);
     }
 
-    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+    public CalendarView(@NonNull Context context, @Nullable AttributeSet attrs,
+            @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
         final TypedArray a = context.obtainStyledAttributes(
@@ -322,7 +331,7 @@
      *
      * @attr ref android.R.styleable#CalendarView_weekDayTextAppearance
      */
-    public void setWeekDayTextAppearance(int resourceId) {
+    public void setWeekDayTextAppearance(@StyleRes int resourceId) {
         mDelegate.setWeekDayTextAppearance(resourceId);
     }
 
@@ -333,7 +342,7 @@
      *
      * @attr ref android.R.styleable#CalendarView_weekDayTextAppearance
      */
-    public int getWeekDayTextAppearance() {
+    public @StyleRes int getWeekDayTextAppearance() {
         return mDelegate.getWeekDayTextAppearance();
     }
 
@@ -344,7 +353,7 @@
      *
      * @attr ref android.R.styleable#CalendarView_dateTextAppearance
      */
-    public void setDateTextAppearance(int resourceId) {
+    public void setDateTextAppearance(@StyleRes int resourceId) {
         mDelegate.setDateTextAppearance(resourceId);
     }
 
@@ -355,7 +364,7 @@
      *
      * @attr ref android.R.styleable#CalendarView_dateTextAppearance
      */
-    public int getDateTextAppearance() {
+    public @StyleRes int getDateTextAppearance() {
         return mDelegate.getDateTextAppearance();
     }
 
@@ -552,36 +561,29 @@
         int getShownWeekCount();
 
         void setSelectedWeekBackgroundColor(@ColorInt int color);
-        @ColorInt
-        int getSelectedWeekBackgroundColor();
+        @ColorInt int getSelectedWeekBackgroundColor();
 
         void setFocusedMonthDateColor(@ColorInt int color);
-        @ColorInt
-        int getFocusedMonthDateColor();
+        @ColorInt int getFocusedMonthDateColor();
 
         void setUnfocusedMonthDateColor(@ColorInt int color);
-        @ColorInt
-        int getUnfocusedMonthDateColor();
+        @ColorInt int getUnfocusedMonthDateColor();
 
         void setWeekNumberColor(@ColorInt int color);
-        @ColorInt
-        int getWeekNumberColor();
+        @ColorInt int getWeekNumberColor();
 
         void setWeekSeparatorLineColor(@ColorInt int color);
-        @ColorInt
-        int getWeekSeparatorLineColor();
+        @ColorInt int getWeekSeparatorLineColor();
 
         void setSelectedDateVerticalBar(@DrawableRes int resourceId);
         void setSelectedDateVerticalBar(Drawable drawable);
         Drawable getSelectedDateVerticalBar();
 
         void setWeekDayTextAppearance(@StyleRes int resourceId);
-        @StyleRes
-        int getWeekDayTextAppearance();
+        @StyleRes int getWeekDayTextAppearance();
 
         void setDateTextAppearance(@StyleRes int resourceId);
-        @StyleRes
-        int getDateTextAppearance();
+        @StyleRes int getDateTextAppearance();
 
         void setMinDate(long minDate);
         long getMinDate();
diff --git a/core/java/android/widget/DropDownListView.java b/core/java/android/widget/DropDownListView.java
index 2fb2101..69e4218 100644
--- a/core/java/android/widget/DropDownListView.java
+++ b/core/java/android/widget/DropDownListView.java
@@ -19,18 +19,10 @@
 
 import com.android.internal.widget.AutoScrollHelper.AbsListViewAutoScroller;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
+import android.annotation.NonNull;
 import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.util.IntProperty;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.widget.TextView;
-import android.widget.ListView;
-
 
 /**
  * Wrapper class for a ListView. This wrapper can hijack the focus to
@@ -41,26 +33,6 @@
  * @hide
  */
 public class DropDownListView extends ListView {
-    /** Duration in milliseconds of the drag-to-open click animation. */
-    private static final long CLICK_ANIM_DURATION = 150;
-
-    /** Target alpha value for drag-to-open click animation. */
-    private static final int CLICK_ANIM_ALPHA = 0x80;
-
-    /** Wrapper around Drawable's <code>alpha</code> property. */
-    private static final IntProperty<Drawable> DRAWABLE_ALPHA =
-            new IntProperty<Drawable>("alpha") {
-                @Override
-                public void setValue(Drawable object, int value) {
-                    object.setAlpha(value);
-                }
-
-                @Override
-                public Integer get(Drawable object) {
-                    return object.getAlpha();
-                }
-            };
-
     /*
      * WARNING: This is a workaround for a touch mode issue.
      *
@@ -99,18 +71,21 @@
     /** Whether to force drawing of the pressed state selector. */
     private boolean mDrawsInPressedState;
 
-    /** Current drag-to-open click animation, if any. */
-    private Animator mClickAnimation;
-
     /** Helper for drag-to-open auto scrolling. */
     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
      */
-    public DropDownListView(Context context, boolean hijackFocus) {
+    public DropDownListView(@NonNull Context context, boolean hijackFocus) {
         this(context, hijackFocus, com.android.internal.R.attr.dropDownListViewStyle);
     }
 
@@ -119,7 +94,7 @@
      *
      * @param context this view's context
      */
-    public DropDownListView(Context context, boolean hijackFocus, int defStyleAttr) {
+    public DropDownListView(@NonNull Context context, boolean hijackFocus, int defStyleAttr) {
         super(context, null, defStyleAttr);
         mHijackFocus = hijackFocus;
         // TODO: Add an API to control this
@@ -132,18 +107,36 @@
     }
 
     @Override
-    public boolean onHoverEvent(MotionEvent ev) {
+    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);
@@ -153,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);
@@ -163,13 +157,20 @@
         return handled;
     }
 
+    @Override
+    protected void drawableStateChanged() {
+        if (mResolveHoverRunnable == null) {
+            super.drawableStateChanged();
+        }
+    }
+
     /**
      * Handles forwarded events.
      *
      * @param activePointerId id of the pointer that activated forwarding
      * @return whether the event was handled
      */
-    public boolean onForwardedEvent(MotionEvent event, int activePointerId) {
+    public boolean onForwardedEvent(@NonNull MotionEvent event, int activePointerId) {
         boolean handledEvent = true;
         boolean clearPressedItem = false;
 
@@ -201,7 +202,8 @@
                 handledEvent = true;
 
                 if (actionMasked == MotionEvent.ACTION_UP) {
-                    clickPressedItem(child, position);
+                    final long id = getItemIdAtPosition(position);
+                    performItemClick(child, position, id);
                 }
                 break;
         }
@@ -226,36 +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;
-    }
-
-    /**
-     * Starts an alpha animation on the selector. When the animation ends,
-     * the list performs a click on the item.
-     */
-    private void clickPressedItem(final View child, final int position) {
-        final long id = getItemIdAtPosition(position);
-        final Animator anim = ObjectAnimator.ofInt(
-                mSelector, DRAWABLE_ALPHA, 0xFF, CLICK_ANIM_ALPHA, 0xFF);
-        anim.setDuration(CLICK_ANIM_DURATION);
-        anim.setInterpolator(new AccelerateDecelerateInterpolator());
-        anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-            public void onAnimationEnd(Animator animation) {
-                performItemClick(child, position, id);
-            }
-        });
-        anim.start();
-
-        if (mClickAnimation != null) {
-            mClickAnimation.cancel();
-        }
-        mClickAnimation = anim;
+    public void setListSelectionHidden(boolean hideListSelection) {
+        mListSelectionHidden = hideListSelection;
     }
 
     private void clearPressedItem() {
@@ -267,14 +247,9 @@
         if (motionView != null) {
             motionView.setPressed(false);
         }
-
-        if (mClickAnimation != null) {
-            mClickAnimation.cancel();
-            mClickAnimation = null;
-        }
     }
 
-    private void setPressedItem(View child, int position, float x, float y) {
+    private void setPressedItem(@NonNull View child, int position, float x, float y) {
         mDrawsInPressedState = true;
 
         // Ordering is essential. First, update the container's pressed state.
@@ -311,11 +286,6 @@
         // Refresh the drawable state to reflect the new pressed state,
         // which will also update the selector state.
         refreshDrawableState();
-
-        if (mClickAnimation != null) {
-            mClickAnimation.cancel();
-            mClickAnimation = null;
-        }
     }
 
     @Override
@@ -376,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 15cea77..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;
@@ -82,6 +83,7 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.RenderNode;
+import android.view.SubMenu;
 import android.view.View;
 import android.view.View.DragShadowBuilder;
 import android.view.View.OnClickListener;
@@ -285,6 +287,9 @@
 
     boolean mIsInsertionActionModeStartPending = false;
 
+    private final SuggestionHelper mSuggestionHelper = new SuggestionHelper();
+    private SuggestionInfo[] mSuggestionInfosInContextMenu;
+
     Editor(TextView textView) {
         mTextView = textView;
         // Synchronize the filter list, which places the undo input filter at the end.
@@ -2369,6 +2374,9 @@
         if (offset == -1) {
             return;
         }
+        mPreserveDetachedSelection = true;
+        stopTextActionMode();
+        mPreserveDetachedSelection = false;
         final boolean isOnSelection = mTextView.hasSelection()
                 && offset >= mTextView.getSelectionStart() && offset <= mTextView.getSelectionEnd();
         if (!isOnSelection) {
@@ -2378,7 +2386,24 @@
             Selection.setSelection((Spannable) mTextView.getText(), offset);
         }
 
-        // TODO: Add suggestions in the context menu.
+        if (shouldOfferToShowSuggestions()) {
+            if (mSuggestionInfosInContextMenu == null) {
+                mSuggestionInfosInContextMenu =
+                        new SuggestionInfo[SuggestionSpan.SUGGESTIONS_MAX_SIZE];
+                for (int i = 0; i < mSuggestionInfosInContextMenu.length; i++) {
+                    mSuggestionInfosInContextMenu[i] = new SuggestionInfo();
+                }
+            }
+            final SubMenu subMenu = menu.addSubMenu(Menu.NONE, Menu.NONE, MENU_ITEM_ORDER_REPLACE,
+                    com.android.internal.R.string.replace);
+            mSuggestionHelper.getSuggestionInfo(mSuggestionInfosInContextMenu);
+            int i = 0;
+            for (final SuggestionInfo info : mSuggestionInfosInContextMenu) {
+                info.mSuggestionEnd = info.mText.length();
+                subMenu.add(Menu.NONE, Menu.NONE, i++, info.mText)
+                        .setOnMenuItemClickListener(mOnContextMenuReplaceItemClickListener);
+            }
+        }
 
         menu.add(Menu.NONE, TextView.ID_UNDO, MENU_ITEM_ORDER_UNDO,
                 com.android.internal.R.string.undo)
@@ -2422,6 +2447,61 @@
         mPreserveDetachedSelection = true;
     }
 
+    private void replaceWithSuggestion(SuggestionInfo suggestionInfo, int spanStart, int spanEnd) {
+        final Editable editable = (Editable) mTextView.getText();
+        final String originalText = TextUtils.substring(editable, spanStart, spanEnd);
+        // SuggestionSpans are removed by replace: save them before
+        SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
+                SuggestionSpan.class);
+        final int length = suggestionSpans.length;
+        int[] suggestionSpansStarts = new int[length];
+        int[] suggestionSpansEnds = new int[length];
+        int[] suggestionSpansFlags = new int[length];
+        for (int i = 0; i < length; i++) {
+            final SuggestionSpan suggestionSpan = suggestionSpans[i];
+            suggestionSpansStarts[i] = editable.getSpanStart(suggestionSpan);
+            suggestionSpansEnds[i] = editable.getSpanEnd(suggestionSpan);
+            suggestionSpansFlags[i] = editable.getSpanFlags(suggestionSpan);
+
+            // Remove potential misspelled flags
+            int suggestionSpanFlags = suggestionSpan.getFlags();
+            if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) != 0) {
+                suggestionSpanFlags &= ~SuggestionSpan.FLAG_MISSPELLED;
+                suggestionSpanFlags &= ~SuggestionSpan.FLAG_EASY_CORRECT;
+                suggestionSpan.setFlags(suggestionSpanFlags);
+            }
+        }
+
+        // Notify source IME of the suggestion pick. Do this before swapping texts.
+        suggestionInfo.mSuggestionSpan.notifySelection(
+                mTextView.getContext(), originalText, suggestionInfo.mSuggestionIndex);
+
+        // Swap text content between actual text and Suggestion span
+        final int suggestionStart = suggestionInfo.mSuggestionStart;
+        final int suggestionEnd = suggestionInfo.mSuggestionEnd;
+        final String suggestion = suggestionInfo.mText.subSequence(
+                suggestionStart, suggestionEnd).toString();
+        mTextView.replaceText_internal(spanStart, spanEnd, suggestion);
+
+        String[] suggestions = suggestionInfo.mSuggestionSpan.getSuggestions();
+        suggestions[suggestionInfo.mSuggestionIndex] = originalText;
+
+        // Restore previous SuggestionSpans
+        final int lengthDelta = suggestion.length() - (spanEnd - spanStart);
+        for (int i = 0; i < length; i++) {
+            // Only spans that include the modified region make sense after replacement
+            // Spans partially included in the replaced region are removed, there is no
+            // way to assign them a valid range after replacement
+            if (suggestionSpansStarts[i] <= spanStart && suggestionSpansEnds[i] >= spanEnd) {
+                mTextView.setSpan_internal(suggestionSpans[i], suggestionSpansStarts[i],
+                        suggestionSpansEnds[i] + lengthDelta, suggestionSpansFlags[i]);
+            }
+        }
+        // Move cursor at the end of the replaced word
+        final int newCursorPosition = spanEnd + lengthDelta;
+        mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
+    }
+
     private final MenuItem.OnMenuItemClickListener mOnContextMenuItemClickListener =
             new MenuItem.OnMenuItemClickListener() {
         @Override
@@ -2433,6 +2513,31 @@
         }
     };
 
+    private final MenuItem.OnMenuItemClickListener mOnContextMenuReplaceItemClickListener =
+            new MenuItem.OnMenuItemClickListener() {
+        @Override
+        public boolean onMenuItemClick(MenuItem item) {
+            int index = item.getOrder();
+            if (index < 0 || index >= mSuggestionInfosInContextMenu.length) {
+                clear();
+                return false;
+            }
+            final Spannable spannable = (Spannable) mTextView.getText();
+            final SuggestionSpan suggestionSpan =
+                    mSuggestionInfosInContextMenu[index].mSuggestionSpan;
+            replaceWithSuggestion(mSuggestionInfosInContextMenu[index],
+                    spannable.getSpanStart(suggestionSpan), spannable.getSpanEnd(suggestionSpan));
+            clear();
+            return true;
+        }
+
+        private void clear() {
+            for (final SuggestionInfo info : mSuggestionInfosInContextMenu) {
+                info.clear();
+            }
+        }
+    };
+
     /**
      * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related
      * pop-up should be displayed.
@@ -2849,6 +2954,131 @@
         }
     }
 
+    private static class SuggestionInfo {
+        // Range of actual suggestion within text
+        int mSuggestionStart, mSuggestionEnd;
+
+        // The SuggestionSpan that this TextView represents
+        @Nullable
+        SuggestionSpan mSuggestionSpan;
+
+        // The index of this suggestion inside suggestionSpan
+        int mSuggestionIndex;
+
+        final SpannableStringBuilder mText = new SpannableStringBuilder();
+
+        void clear() {
+            mSuggestionSpan = null;
+            mText.clear();
+        }
+    }
+
+    private class SuggestionHelper {
+        private final Comparator<SuggestionSpan> mSuggestionSpanComparator =
+                new SuggestionSpanComparator();
+        private final HashMap<SuggestionSpan, Integer> mSpansLengths =
+                new HashMap<SuggestionSpan, Integer>();
+
+        private class SuggestionSpanComparator implements Comparator<SuggestionSpan> {
+            public int compare(SuggestionSpan span1, SuggestionSpan span2) {
+                final int flag1 = span1.getFlags();
+                final int flag2 = span2.getFlags();
+                if (flag1 != flag2) {
+                    // The order here should match what is used in updateDrawState
+                    final boolean easy1 = (flag1 & SuggestionSpan.FLAG_EASY_CORRECT) != 0;
+                    final boolean easy2 = (flag2 & SuggestionSpan.FLAG_EASY_CORRECT) != 0;
+                    final boolean misspelled1 = (flag1 & SuggestionSpan.FLAG_MISSPELLED) != 0;
+                    final boolean misspelled2 = (flag2 & SuggestionSpan.FLAG_MISSPELLED) != 0;
+                    if (easy1 && !misspelled1) return -1;
+                    if (easy2 && !misspelled2) return 1;
+                    if (misspelled1) return -1;
+                    if (misspelled2) return 1;
+                }
+
+                return mSpansLengths.get(span1).intValue() - mSpansLengths.get(span2).intValue();
+            }
+        }
+
+        /**
+         * Returns the suggestion spans that cover the current cursor position. The suggestion
+         * spans are sorted according to the length of text that they are attached to.
+         */
+        private SuggestionSpan[] getSortedSuggestionSpans() {
+            int pos = mTextView.getSelectionStart();
+            Spannable spannable = (Spannable) mTextView.getText();
+            SuggestionSpan[] suggestionSpans = spannable.getSpans(pos, pos, SuggestionSpan.class);
+
+            mSpansLengths.clear();
+            for (SuggestionSpan suggestionSpan : suggestionSpans) {
+                int start = spannable.getSpanStart(suggestionSpan);
+                int end = spannable.getSpanEnd(suggestionSpan);
+                mSpansLengths.put(suggestionSpan, Integer.valueOf(end - start));
+            }
+
+            // The suggestions are sorted according to their types (easy correction first, then
+            // misspelled) and to the length of the text that they cover (shorter first).
+            Arrays.sort(suggestionSpans, mSuggestionSpanComparator);
+            mSpansLengths.clear();
+
+            return suggestionSpans;
+        }
+
+        /**
+         * Gets the SuggestionInfo list that contains suggestion information at the current cursor
+         * position.
+         *
+         * @param suggestionInfos SuggestionInfo array the results will be set.
+         * @return the number of suggestions actually fetched.
+         */
+        public int getSuggestionInfo(SuggestionInfo[] suggestionInfos) {
+            final Spannable spannable = (Spannable) mTextView.getText();
+            final SuggestionSpan[] suggestionSpans = getSortedSuggestionSpans();
+            final int nbSpans = suggestionSpans.length;
+            if (nbSpans == 0) return 0;
+
+            int numberOfSuggestions = 0;
+            for (int spanIndex = 0; spanIndex < nbSpans; spanIndex++) {
+                final SuggestionSpan suggestionSpan = suggestionSpans[spanIndex];
+                final int spanStart = spannable.getSpanStart(suggestionSpan);
+                final int spanEnd = spannable.getSpanEnd(suggestionSpan);
+
+                final String[] suggestions = suggestionSpan.getSuggestions();
+                final int nbSuggestions = suggestions.length;
+                for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
+                    final String suggestion = suggestions[suggestionIndex];
+                    boolean suggestionIsDuplicate = false;
+                    for (int i = 0; i < numberOfSuggestions; i++) {
+                        if (suggestionInfos[i].mText.toString().equals(suggestion)) {
+                            final SuggestionSpan otherSuggestionSpan =
+                                    suggestionInfos[i].mSuggestionSpan;
+                            final int otherSpanStart = spannable.getSpanStart(otherSuggestionSpan);
+                            final int otherSpanEnd = spannable.getSpanEnd(otherSuggestionSpan);
+                            if (spanStart == otherSpanStart && spanEnd == otherSpanEnd) {
+                                suggestionIsDuplicate = true;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (suggestionIsDuplicate) {
+                        continue;
+                    }
+                    SuggestionInfo suggestionInfo = suggestionInfos[numberOfSuggestions];
+                    suggestionInfo.mSuggestionSpan = suggestionSpan;
+                    suggestionInfo.mSuggestionIndex = suggestionIndex;
+                    suggestionInfo.mSuggestionStart = 0;
+                    suggestionInfo.mSuggestionEnd = suggestion.length();
+                    suggestionInfo.mText.replace(0, suggestionInfo.mText.length(), suggestion);
+                    numberOfSuggestions++;
+                    if (numberOfSuggestions >= suggestionInfos.length) {
+                        return numberOfSuggestions;
+                    }
+                }
+            }
+            return numberOfSuggestions;
+        }
+    }
+
     @VisibleForTesting
     public class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener {
         private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
@@ -2862,8 +3092,6 @@
         private boolean mCursorWasVisibleBeforeSuggestions;
         private boolean mIsShowingUp = false;
         private SuggestionAdapter mSuggestionsAdapter;
-        private final Comparator<SuggestionSpan> mSuggestionSpanComparator;
-        private final HashMap<SuggestionSpan, Integer> mSpansLengths;
         private final TextAppearanceSpan mHighlightSpan = new TextAppearanceSpan(
                 mTextView.getContext(), mTextView.mTextEditSuggestionHighlightStyle);
         private TextView mAddToDictionaryButton;
@@ -2871,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()) {
@@ -2895,15 +3119,13 @@
 
         public SuggestionsPopupWindow() {
             mCursorWasVisibleBeforeSuggestions = mCursorVisible;
-            mSuggestionSpanComparator = new SuggestionSpanComparator();
-            mSpansLengths = new HashMap<SuggestionSpan, Integer>();
         }
 
         @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);
         }
@@ -2987,24 +3209,6 @@
             mIsShowingUp = false;
         }
 
-        private final class SuggestionInfo {
-            int suggestionStart, suggestionEnd; // range of actual suggestion within text
-
-            // the SuggestionSpan that this TextView represents
-            @Nullable
-            SuggestionSpan suggestionSpan;
-
-            int suggestionIndex; // the index of this suggestion inside suggestionSpan
-
-            @Nullable
-            final SpannableStringBuilder text = new SpannableStringBuilder();
-
-            void clear() {
-                suggestionSpan = null;
-                text.clear();
-            }
-        }
-
         private class SuggestionAdapter extends BaseAdapter {
             private LayoutInflater mInflater = (LayoutInflater) mTextView.getContext().
                     getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -3034,55 +3238,11 @@
                 }
 
                 final SuggestionInfo suggestionInfo = mSuggestionInfos[position];
-                textView.setText(suggestionInfo.text);
+                textView.setText(suggestionInfo.mText);
                 return textView;
             }
         }
 
-        private class SuggestionSpanComparator implements Comparator<SuggestionSpan> {
-            public int compare(SuggestionSpan span1, SuggestionSpan span2) {
-                final int flag1 = span1.getFlags();
-                final int flag2 = span2.getFlags();
-                if (flag1 != flag2) {
-                    // The order here should match what is used in updateDrawState
-                    final boolean easy1 = (flag1 & SuggestionSpan.FLAG_EASY_CORRECT) != 0;
-                    final boolean easy2 = (flag2 & SuggestionSpan.FLAG_EASY_CORRECT) != 0;
-                    final boolean misspelled1 = (flag1 & SuggestionSpan.FLAG_MISSPELLED) != 0;
-                    final boolean misspelled2 = (flag2 & SuggestionSpan.FLAG_MISSPELLED) != 0;
-                    if (easy1 && !misspelled1) return -1;
-                    if (easy2 && !misspelled2) return 1;
-                    if (misspelled1) return -1;
-                    if (misspelled2) return 1;
-                }
-
-                return mSpansLengths.get(span1).intValue() - mSpansLengths.get(span2).intValue();
-            }
-        }
-
-        /**
-         * Returns the suggestion spans that cover the current cursor position. The suggestion
-         * spans are sorted according to the length of text that they are attached to.
-         */
-        private SuggestionSpan[] getSuggestionSpans() {
-            int pos = mTextView.getSelectionStart();
-            Spannable spannable = (Spannable) mTextView.getText();
-            SuggestionSpan[] suggestionSpans = spannable.getSpans(pos, pos, SuggestionSpan.class);
-
-            mSpansLengths.clear();
-            for (SuggestionSpan suggestionSpan : suggestionSpans) {
-                int start = spannable.getSpanStart(suggestionSpan);
-                int end = spannable.getSpanEnd(suggestionSpan);
-                mSpansLengths.put(suggestionSpan, Integer.valueOf(end - start));
-            }
-
-            // The suggestions are sorted according to their types (easy correction first, then
-            // misspelled) and to the length of the text that they cover (shorter first).
-            Arrays.sort(suggestionSpans, mSuggestionSpanComparator);
-            mSpansLengths.clear();
-
-            return suggestionSpans;
-        }
-
         @VisibleForTesting
         public ViewGroup getContentViewForTesting() {
             return mContentView;
@@ -3166,66 +3326,26 @@
 
         private boolean updateSuggestions() {
             Spannable spannable = (Spannable) mTextView.getText();
-            SuggestionSpan[] suggestionSpans = getSuggestionSpans();
+            mNumberOfSuggestions =
+                    mSuggestionHelper.getSuggestionInfo(mSuggestionInfos);
+            if (mNumberOfSuggestions == 0) {
+                return false;
+            }
 
-            final int nbSpans = suggestionSpans.length;
-            // Suggestions are shown after a delay: the underlying spans may have been removed
-            if (nbSpans == 0) return false;
-
-            mNumberOfSuggestions = 0;
             int spanUnionStart = mTextView.getText().length();
             int spanUnionEnd = 0;
 
             mMisspelledSpan = null;
-            int underlineColor = 0;
-
-            for (int spanIndex = 0; spanIndex < nbSpans; spanIndex++) {
-                SuggestionSpan suggestionSpan = suggestionSpans[spanIndex];
-                final int spanStart = spannable.getSpanStart(suggestionSpan);
-                final int spanEnd = spannable.getSpanEnd(suggestionSpan);
-                spanUnionStart = Math.min(spanStart, spanUnionStart);
-                spanUnionEnd = Math.max(spanEnd, spanUnionEnd);
-
+            for (int i = 0; i < mNumberOfSuggestions; i++) {
+                final SuggestionInfo suggestionInfo = mSuggestionInfos[i];
+                final SuggestionSpan suggestionSpan = suggestionInfo.mSuggestionSpan;
                 if ((suggestionSpan.getFlags() & SuggestionSpan.FLAG_MISSPELLED) != 0) {
                     mMisspelledSpan = suggestionSpan;
                 }
-
-                // The first span dictates the background color of the highlighted text
-                if (spanIndex == 0) underlineColor = suggestionSpan.getUnderlineColor();
-
-                String[] suggestions = suggestionSpan.getSuggestions();
-                int nbSuggestions = suggestions.length;
-                for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
-                    String suggestion = suggestions[suggestionIndex];
-
-                    boolean suggestionIsDuplicate = false;
-                    for (int i = 0; i < mNumberOfSuggestions; i++) {
-                        if (mSuggestionInfos[i].text.toString().equals(suggestion)) {
-                            SuggestionSpan otherSuggestionSpan = mSuggestionInfos[i].suggestionSpan;
-                            final int otherSpanStart = spannable.getSpanStart(otherSuggestionSpan);
-                            final int otherSpanEnd = spannable.getSpanEnd(otherSuggestionSpan);
-                            if (spanStart == otherSpanStart && spanEnd == otherSpanEnd) {
-                                suggestionIsDuplicate = true;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (!suggestionIsDuplicate) {
-                        SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
-                        suggestionInfo.suggestionSpan = suggestionSpan;
-                        suggestionInfo.suggestionIndex = suggestionIndex;
-                        suggestionInfo.text.replace(0, suggestionInfo.text.length(), suggestion);
-
-                        mNumberOfSuggestions++;
-
-                        if (mNumberOfSuggestions == MAX_NUMBER_SUGGESTIONS) {
-                            // Also end outer for loop
-                            spanIndex = nbSpans;
-                            break;
-                        }
-                    }
-                }
+                final int spanStart = spannable.getSpanStart(suggestionSpan);
+                final int spanEnd = spannable.getSpanEnd(suggestionSpan);
+                spanUnionStart = Math.min(spanUnionStart, spanStart);
+                spanUnionEnd = Math.max(spanUnionEnd, spanEnd);
             }
 
             for (int i = 0; i < mNumberOfSuggestions; i++) {
@@ -3244,6 +3364,7 @@
             mAddToDictionaryButton.setVisibility(addToDictionaryButtonVisibility);
 
             if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
+            final int underlineColor = mSuggestionInfos[0].mSuggestionSpan.getUnderlineColor();
             if (underlineColor == 0) {
                 // Fallback on the default highlight color when the first span does not provide one
                 mSuggestionRangeSpan.setBackgroundColor(mTextView.mHighlightColor);
@@ -3263,21 +3384,21 @@
         private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionStart,
                 int unionEnd) {
             final Spannable text = (Spannable) mTextView.getText();
-            final int spanStart = text.getSpanStart(suggestionInfo.suggestionSpan);
-            final int spanEnd = text.getSpanEnd(suggestionInfo.suggestionSpan);
+            final int spanStart = text.getSpanStart(suggestionInfo.mSuggestionSpan);
+            final int spanEnd = text.getSpanEnd(suggestionInfo.mSuggestionSpan);
 
             // Adjust the start/end of the suggestion span
-            suggestionInfo.suggestionStart = spanStart - unionStart;
-            suggestionInfo.suggestionEnd = suggestionInfo.suggestionStart
-                    + suggestionInfo.text.length();
+            suggestionInfo.mSuggestionStart = spanStart - unionStart;
+            suggestionInfo.mSuggestionEnd = suggestionInfo.mSuggestionStart
+                    + suggestionInfo.mText.length();
 
-            suggestionInfo.text.setSpan(mHighlightSpan, 0, suggestionInfo.text.length(),
+            suggestionInfo.mText.setSpan(mHighlightSpan, 0, suggestionInfo.mText.length(),
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
             // Add the text before and after the span.
             final String textAsString = text.toString();
-            suggestionInfo.text.insert(0, textAsString.substring(unionStart, spanStart));
-            suggestionInfo.text.append(textAsString.substring(spanEnd, unionEnd));
+            suggestionInfo.mText.insert(0, textAsString.substring(unionStart, spanStart));
+            suggestionInfo.mText.append(textAsString.substring(spanEnd, unionEnd));
         }
 
         @Override
@@ -3285,69 +3406,14 @@
             Editable editable = (Editable) mTextView.getText();
             SuggestionInfo suggestionInfo = mSuggestionInfos[position];
 
-            final int spanStart = editable.getSpanStart(suggestionInfo.suggestionSpan);
-            final int spanEnd = editable.getSpanEnd(suggestionInfo.suggestionSpan);
+            final int spanStart = editable.getSpanStart(suggestionInfo.mSuggestionSpan);
+            final int spanEnd = editable.getSpanEnd(suggestionInfo.mSuggestionSpan);
             if (spanStart < 0 || spanEnd <= spanStart) {
                 // Span has been removed
                 hideWithCleanUp();
                 return;
             }
-
-            final String originalText = TextUtils.substring(editable, spanStart, spanEnd);
-
-            // SuggestionSpans are removed by replace: save them before
-            final SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
-                    SuggestionSpan.class);
-            final int length = suggestionSpans.length;
-            final int[] suggestionSpansStarts = new int[length];
-            final int[] suggestionSpansEnds = new int[length];
-            final int[] suggestionSpansFlags = new int[length];
-            for (int i = 0; i < length; i++) {
-                final SuggestionSpan suggestionSpan = suggestionSpans[i];
-                suggestionSpansStarts[i] = editable.getSpanStart(suggestionSpan);
-                suggestionSpansEnds[i] = editable.getSpanEnd(suggestionSpan);
-                suggestionSpansFlags[i] = editable.getSpanFlags(suggestionSpan);
-
-                // Remove potential misspelled flags
-                int suggestionSpanFlags = suggestionSpan.getFlags();
-                if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) {
-                    suggestionSpanFlags &= ~SuggestionSpan.FLAG_MISSPELLED;
-                    suggestionSpanFlags &= ~SuggestionSpan.FLAG_EASY_CORRECT;
-                    suggestionSpan.setFlags(suggestionSpanFlags);
-                }
-            }
-
-            final int suggestionStart = suggestionInfo.suggestionStart;
-            final int suggestionEnd = suggestionInfo.suggestionEnd;
-            final String suggestion = suggestionInfo.text.subSequence(
-                    suggestionStart, suggestionEnd).toString();
-            mTextView.replaceText_internal(spanStart, spanEnd, suggestion);
-
-            // Notify source IME of the suggestion pick. Do this before
-            // swaping texts.
-            suggestionInfo.suggestionSpan.notifySelection(
-                    mTextView.getContext(), originalText, suggestionInfo.suggestionIndex);
-
-            // Swap text content between actual text and Suggestion span
-            final String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
-            suggestions[suggestionInfo.suggestionIndex] = originalText;
-
-            // Restore previous SuggestionSpans
-            final int lengthDifference = suggestion.length() - (spanEnd - spanStart);
-            for (int i = 0; i < length; i++) {
-                // Only spans that include the modified region make sense after replacement
-                // Spans partially included in the replaced region are removed, there is no
-                // way to assign them a valid range after replacement
-                if (suggestionSpansStarts[i] <= spanStart &&
-                        suggestionSpansEnds[i] >= spanEnd) {
-                    mTextView.setSpan_internal(suggestionSpans[i], suggestionSpansStarts[i],
-                            suggestionSpansEnds[i] + lengthDifference, suggestionSpansFlags[i]);
-                }
-            }
-
-            // Move cursor at the end of the replaced word
-            final int newCursorPosition = spanEnd + lengthDifference;
-            mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
+            replaceWithSuggestion(suggestionInfo, spanStart, spanEnd);
             hideWithCleanUp();
         }
     }
diff --git a/core/java/android/widget/ForwardingListener.java b/core/java/android/widget/ForwardingListener.java
index 7ddeff9..b383e1c 100644
--- a/core/java/android/widget/ForwardingListener.java
+++ b/core/java/android/widget/ForwardingListener.java
@@ -53,12 +53,6 @@
     /** Whether this listener is currently forwarding touch events. */
     private boolean mForwarding;
 
-    /**
-     * Whether forwarding was initiated by a long-press. If so, we won't
-     * force the window to dismiss when the touch stream ends.
-     */
-    private boolean mWasLongPress;
-
     /** The id of the first pointer down in the current event stream. */
     private int mActivePointerId;
 
@@ -172,7 +166,6 @@
         switch (actionMasked) {
             case MotionEvent.ACTION_DOWN:
                 mActivePointerId = srcEvent.getPointerId(0);
-                mWasLongPress = false;
 
                 if (mDisallowIntercept == null) {
                     mDisallowIntercept = new DisallowIntercept();
@@ -243,7 +236,6 @@
         e.recycle();
 
         mForwarding = true;
-        mWasLongPress = true;
     }
 
     /**
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/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index b95bc28..dcadb6a 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -16,18 +16,20 @@
 
 package android.widget;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
+import com.android.internal.R;
+import com.android.internal.view.menu.ShowableListMenu;
+
+import android.annotation.AttrRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
-import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.util.IntProperty;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.KeyEvent;
@@ -38,13 +40,7 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.WindowManager;
-import android.view.animation.AccelerateDecelerateInterpolator;
-
-import com.android.internal.R;
-import com.android.internal.view.menu.ShowableListMenu;
-import com.android.internal.widget.AutoScrollHelper.AbsListViewAutoScroller;
-
-import java.util.Locale;
+import android.widget.AdapterView.OnItemSelectedListener;
 
 /**
  * A ListPopupWindow anchors itself to a host view and displays a
@@ -78,6 +74,7 @@
     private int mDropDownVerticalOffset;
     private int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
     private boolean mDropDownVerticalOffsetSet;
+    private boolean mIsAnimatedFromAnchor = true;
 
     private int mDropDownGravity = Gravity.NO_GRAVITY;
 
@@ -105,12 +102,16 @@
 
     private final Handler mHandler;
 
-    private Rect mTempRect = new Rect();
+    private final Rect mTempRect = new Rect();
+
+    /**
+     * Optional anchor-relative bounds to be used as the transition epicenter.
+     * When {@code null}, the anchor bounds are used as the epicenter.
+     */
+    private Rect mEpicenterBounds;
 
     private boolean mModal;
 
-    private int mLayoutDirection;
-
     PopupWindow mPopup;
 
     /**
@@ -174,7 +175,7 @@
      * 
      * @param context Context used for contained views.
      */
-    public ListPopupWindow(Context context) {
+    public ListPopupWindow(@NonNull Context context) {
         this(context, null, com.android.internal.R.attr.listPopupWindowStyle, 0);
     }
 
@@ -185,7 +186,7 @@
      * @param context Context used for contained views.
      * @param attrs Attributes from inflating parent views used to style the popup.
      */
-    public ListPopupWindow(Context context, AttributeSet attrs) {
+    public ListPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.listPopupWindowStyle, 0);
     }
 
@@ -197,7 +198,8 @@
      * @param attrs Attributes from inflating parent views used to style the popup.
      * @param defStyleAttr Default style attribute to use for popup content.
      */
-    public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
+    public ListPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs,
+            @AttrRes int defStyleAttr) {
         this(context, attrs, defStyleAttr, 0);
     }
 
@@ -210,7 +212,8 @@
      * @param defStyleAttr Style attribute to read for default styling of popup content.
      * @param defStyleRes Style resource ID to use for default styling of popup content.
      */
-    public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+    public ListPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs,
+            @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
         mContext = context;
         mHandler = new Handler(context.getMainLooper());
 
@@ -227,9 +230,6 @@
 
         mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes);
         mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
-        // Set the default layout direction to match the default locale one
-        final Locale locale = mContext.getResources().getConfiguration().locale;
-        mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(locale);
     }
 
     /**
@@ -238,7 +238,7 @@
      *
      * @param adapter The adapter to use to create this window's content.
      */
-    public void setAdapter(ListAdapter adapter) {
+    public void setAdapter(@Nullable ListAdapter adapter) {
         if (mObserver == null) {
             mObserver = new PopupDataSetObserver();
         } else if (mAdapter != null) {
@@ -371,7 +371,7 @@
     /**
      * @return The background drawable for the popup window.
      */
-    public Drawable getBackground() {
+    public @Nullable Drawable getBackground() {
         return mPopup.getBackground();
     }
 
@@ -380,7 +380,7 @@
      * 
      * @param d A drawable to set as the background.
      */
-    public void setBackgroundDrawable(Drawable d) {
+    public void setBackgroundDrawable(@Nullable Drawable d) {
         mPopup.setBackgroundDrawable(d);
     }
 
@@ -389,7 +389,7 @@
      * 
      * @param animationStyle Animation style to use.
      */
-    public void setAnimationStyle(int animationStyle) {
+    public void setAnimationStyle(@StyleRes int animationStyle) {
         mPopup.setAnimationStyle(animationStyle);
     }
 
@@ -399,7 +399,7 @@
      * 
      * @return Animation style that will be used.
      */
-    public int getAnimationStyle() {
+    public @StyleRes int getAnimationStyle() {
         return mPopup.getAnimationStyle();
     }
 
@@ -408,7 +408,7 @@
      * 
      * @return The popup's anchor view
      */
-    public View getAnchorView() {
+    public @Nullable View getAnchorView() {
         return mDropDownAnchorView;
     }
 
@@ -418,7 +418,7 @@
      * 
      * @param anchor The view to use as an anchor.
      */
-    public void setAnchorView(View anchor) {
+    public void setAnchorView(@Nullable View anchor) {
         mDropDownAnchorView = anchor;
     }
 
@@ -459,6 +459,17 @@
     }
 
     /**
+     * Specifies the anchor-relative bounds of the popup's transition
+     * epicenter.
+     *
+     * @param bounds anchor-relative bounds
+     * @hide
+     */
+    public void setEpicenterBounds(Rect bounds) {
+        mEpicenterBounds = bounds;
+    }
+
+    /**
      * Set the gravity of the dropdown list. This is commonly used to
      * set gravity to START or END for alignment with the anchor.
      *
@@ -537,7 +548,7 @@
      * 
      * @see ListView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener)
      */
-    public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) {
+    public void setOnItemClickListener(@Nullable AdapterView.OnItemClickListener clickListener) {
         mItemClickListener = clickListener;
     }
 
@@ -546,9 +557,9 @@
      * 
      * @param selectedListener Listener to register.
      * 
-     * @see ListView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener)
+     * @see ListView#setOnItemSelectedListener(OnItemSelectedListener)
      */
-    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener selectedListener) {
+    public void setOnItemSelectedListener(@Nullable OnItemSelectedListener selectedListener) {
         mItemSelectedListener = selectedListener;
     }
 
@@ -558,7 +569,7 @@
      * 
      * @param prompt View to use as an informational prompt.
      */
-    public void setPromptView(View prompt) {
+    public void setPromptView(@Nullable View prompt) {
         boolean showing = isShowing();
         if (showing) {
             removePromptView();
@@ -656,6 +667,7 @@
             // only set this if the dropdown is not always visible
             mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
             mPopup.setTouchInterceptor(mTouchInterceptor);
+            mPopup.setEpicenterBounds(mEpicenterBounds);
             mPopup.showAsDropDown(getAnchorView(), mDropDownHorizontalOffset,
                     mDropDownVerticalOffset, mDropDownGravity);
             mDropDownList.setSelection(ListView.INVALID_POSITION);
@@ -686,7 +698,7 @@
      *
      * @param listener Listener that will be notified when the popup is dismissed.
      */
-    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
+    public void setOnDismissListener(@Nullable PopupWindow.OnDismissListener listener) {
         mPopup.setOnDismissListener(listener);
     }
 
@@ -795,7 +807,7 @@
     /**
      * @return The currently selected item or null if the popup is not showing.
      */
-    public Object getSelectedItem() {
+    public @Nullable Object getSelectedItem() {
         if (!isShowing()) {
             return null;
         }
@@ -834,7 +846,7 @@
      * 
      * @see ListView#getSelectedView()
      */
-    public View getSelectedView() {
+    public @Nullable View getSelectedView() {
         if (!isShowing()) {
             return null;
         }
@@ -846,11 +858,11 @@
      * Only valid when {@link #isShowing()} == {@code true}.
      */
     @Override
-    public ListView getListView() {
+    public @Nullable ListView getListView() {
         return mDropDownList;
     }
 
-    DropDownListView createDropDownListView(Context context, boolean hijackFocus) {
+    @NonNull DropDownListView createDropDownListView(Context context, boolean hijackFocus) {
         return new DropDownListView(context, hijackFocus);
     }
 
@@ -874,7 +886,7 @@
      * 
      * @see #setModal(boolean)
      */
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
+    public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
         // when the drop down is shown, we drive it directly
         if (isShowing()) {
             // the key events are forwarded to the list in the drop down view
@@ -969,7 +981,7 @@
      * 
      * @see #setModal(boolean)
      */
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
+    public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
         if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) {
             boolean consumed = mDropDownList.onKeyUp(keyCode, event);
             if (consumed && KeyEvent.isConfirmKey(keyCode)) {
@@ -993,7 +1005,7 @@
      * 
      * @see #setModal(boolean)
      */
-    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+    public boolean onKeyPreIme(int keyCode, @NonNull KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_BACK && isShowing()) {
             // special case for the back key, we do not even try to send it
             // to the drop down list but instead, consume it immediately
@@ -1159,7 +1171,6 @@
 
             mPopup.setContentView(dropDownView);
         } else {
-            dropDownView = (ViewGroup) mPopup.getContentView();
             final View view = mPromptView;
             if (view != null) {
                 LinearLayout.LayoutParams hintParams =
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 7e98193..584df08 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -150,6 +150,7 @@
 
     private Transition mEnterTransition;
     private Transition mExitTransition;
+    private Rect mEpicenterBounds;
 
     private boolean mAboveAnchor;
     private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
@@ -345,6 +346,25 @@
         mExitTransition = exitTransition;
     }
 
+    /**
+     * Sets the bounds used as the epicenter of the enter and exit transitions.
+     * <p>
+     * Transitions use a point or Rect, referred to as the epicenter, to orient
+     * the direction of travel. For popup windows, the anchor view bounds are
+     * used as the default epicenter.
+     * <p>
+     * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more
+     * information about how transition epicenters.
+     *
+     * @param bounds the epicenter bounds relative to the anchor view, or
+     *               {@code null} to use the default epicenter
+     * @see #getTransitionEpicenter()
+     * @hide
+     */
+    public void setEpicenterBounds(Rect bounds) {
+        mEpicenterBounds = bounds;
+    }
+
     private Transition getTransition(int resId) {
         if (resId != 0 && resId != R.transition.no_transition) {
             final TransitionInflater inflater = TransitionInflater.from(mContext);
@@ -1621,7 +1641,7 @@
             p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
             mWindowManager.updateViewLayout(decorView, p);
 
-            final Rect epicenter = getRelativeAnchorBounds();
+            final Rect epicenter = getTransitionEpicenter();
             exitTransition.setEpicenterCallback(new EpicenterCallback() {
                 @Override
                 public Rect onGetEpicenter(Transition transition) {
@@ -1646,7 +1666,17 @@
         }
     }
 
-    private Rect getRelativeAnchorBounds() {
+    /**
+     * Returns the window-relative epicenter bounds to be used by enter and
+     * exit transitions.
+     * <p>
+     * <strong>Note:</strong> This is distinct from the rect passed to
+     * {@link #setEpicenterBounds(Rect)}, which is anchor-relative.
+     *
+     * @return the window-relative epicenter bounds to be used by enter and
+     *         exit transitions
+     */
+    private Rect getTransitionEpicenter() {
         final View anchor = mAnchor != null ? mAnchor.get() : null;
         final View decor = mDecorView;
         if (anchor == null || decor == null) {
@@ -1659,6 +1689,15 @@
         // Compute the position of the anchor relative to the popup.
         final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight());
         bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]);
+
+        // Use anchor-relative epicenter, if specified.
+        if (mEpicenterBounds != null) {
+            final int offsetX = bounds.left;
+            final int offsetY = bounds.top;
+            bounds.set(mEpicenterBounds);
+            bounds.offset(offsetX, offsetY);
+        }
+
         return bounds;
     }
 
@@ -2031,7 +2070,7 @@
                             observer.removeOnGlobalLayoutListener(this);
                         }
 
-                        final Rect epicenter = getRelativeAnchorBounds();
+                        final Rect epicenter = getTransitionEpicenter();
                         enterTransition.setEpicenterCallback(new EpicenterCallback() {
                             @Override
                             public Rect onGetEpicenter(Transition transition) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d46c6f9..81ebdb3 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6440,6 +6440,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 +6450,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;
     }
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 8e711b0..06daf61 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1946,6 +1946,9 @@
     public void setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb) {
         mActionMenuPresenterCallback = pcb;
         mMenuBuilderCallback = mcb;
+        if (mMenuView != null) {
+            mMenuView.setMenuCallbacks(pcb, mcb);
+        }
     }
 
     /**
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
new file mode 100644
index 0000000..53d7793
--- /dev/null
+++ b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
@@ -0,0 +1,136 @@
+/*
+ * 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.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+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;
+
+import com.android.internal.R;
+
+/**
+ * Activity to confirm with the user that it is ok to create a new user, as requested by
+ * an app. It has to do some checks to decide what kind of prompt the user should be shown.
+ * Particularly, it needs to check if the account requested already exists on another user.
+ */
+public class ConfirmUserCreationActivity extends AlertActivity
+        implements DialogInterface.OnClickListener {
+
+    private static final String TAG = "CreateUser";
+
+    private String mUserName;
+    private String mAccountName;
+    private String mAccountType;
+    private PersistableBundle mAccountOptions;
+    private boolean mCanProceed;
+    private UserManager mUserManager;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        Intent intent = getIntent();
+        mUserName = intent.getStringExtra(UserManager.EXTRA_USER_NAME);
+        mAccountName = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_NAME);
+        mAccountType = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_TYPE);
+        mAccountOptions = (PersistableBundle)
+                intent.getParcelableExtra(UserManager.EXTRA_USER_ACCOUNT_OPTIONS);
+
+        mUserManager = getSystemService(UserManager.class);
+
+        String message = checkUserCreationRequirements();
+
+        final AlertController.AlertParams ap = mAlertParams;
+        ap.mMessage = message;
+        ap.mPositiveButtonText = getString(android.R.string.ok);
+        ap.mPositiveButtonListener = this;
+
+        // Show the negative button if the user actually has a choice
+        if (mCanProceed) {
+            ap.mNegativeButtonText = getString(android.R.string.cancel);
+            ap.mNegativeButtonListener = this;
+        }
+        setupAlert();
+    }
+
+    private String checkUserCreationRequirements() {
+        final String callingPackage = getCallingPackage();
+        if (callingPackage == null) {
+            throw new SecurityException(
+                    "User Creation intent must be launched with startActivityForResult");
+        }
+        final ApplicationInfo appInfo;
+        try {
+            appInfo = getPackageManager().getApplicationInfo(callingPackage, 0);
+        } catch (NameNotFoundException nnfe) {
+            throw new SecurityException(
+                    "Cannot find the calling package");
+        }
+        final String message;
+        // Check the user restrictions
+        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
+        final Account account = new Account(mAccountName, mAccountType);
+        boolean accountExists = mAccountName != null && mAccountType != null
+                && (AccountManager.get(this).someUserHasAccount(account)
+                    | mUserManager.someUserHasSeedAccount(mAccountName, mAccountType));
+        mCanProceed = true;
+        final String appName = appInfo.loadLabel(getPackageManager()).toString();
+        if (cantCreateUser) {
+            message = getString(R.string.user_creation_cannot_add, appName);
+            mCanProceed = false;
+        } else if (cantCreateAnyMoreUsers) {
+            message = getString(R.string.user_creation_cannot_add_any_more, appName);
+            mCanProceed = false;
+        } else if (accountExists) {
+            message = getString(R.string.user_creation_account_exists, appName, mAccountName);
+        } else {
+            message = getString(R.string.user_creation_adding, appName, mAccountName);
+        }
+        return message;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        setResult(RESULT_CANCELED);
+        if (which == BUTTON_POSITIVE && mCanProceed) {
+            Log.i(TAG, "Ok, creating user");
+            UserInfo user = mUserManager.createUser(mUserName, 0);
+            if (user == null) {
+                Log.e(TAG, "Couldn't create user");
+                finish();
+                return;
+            }
+            mUserManager.setSeedAccountData(user.id, mAccountName, mAccountType, mAccountOptions);
+            setResult(RESULT_OK);
+        }
+        finish();
+    }
+}
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/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index ce4fc06..b0b25d3 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -63,6 +63,22 @@
     public static final int PROFILE_CHALLENGE = 271;
     public static final int QS_BATTERY_DETAIL = 272;
 
+    /**
+     * Logged when the user goes into the overview history.
+     */
+    public static final int OVERVIEW_HISTORY = 273;
+
+    /**
+     * Logged when the user pages through overview.
+     */
+    public static final int ACTION_OVERVIEW_PAGE = 274;
+
+    /**
+     * Logged when the user launches a task from overview.
+     */
+    public static final int ACTION_OVERVIEW_SELECT = 275;
+
+
     public static void visible(Context context, int category) throws IllegalArgumentException {
         if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
             throw new IllegalArgumentException("Must define metric category");
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/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index b3222f0..ed4722d 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -21,6 +21,7 @@
 import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.Slog;
+import android.text.TextUtils;
 
 import com.android.internal.util.Preconditions;
 
@@ -139,14 +140,24 @@
     }
 
     public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
-            int dexFlags) throws InstallerException {
-        dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /* outputPath */, dexFlags);
+            int dexFlags, String volumeUuid, boolean useProfiles) throws InstallerException {
+        dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded,
+                null /*outputPath*/, dexFlags, volumeUuid, useProfiles);
     }
 
     public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
-            int dexoptNeeded, String outputPath, int dexFlags) throws InstallerException {
-        execute("dexopt", apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath,
-                dexFlags);
+            int dexoptNeeded, String outputPath, int dexFlags, String volumeUuid,
+            boolean useProfiles) throws InstallerException {
+        execute("dexopt",
+                apkPath,
+                uid,
+                pkgName,
+                instructionSet,
+                dexoptNeeded,
+                outputPath,
+                dexFlags,
+                volumeUuid,
+                useProfiles ? '1' : '0');
     }
 
     private boolean connect() {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index eecc0ee..6ad9e20 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -500,8 +500,11 @@
                 final int dexoptNeeded = DexFile.getDexOptNeeded(
                         classPathElement, "*", instructionSet, false /* defer */);
                 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
+                    // System server is fully AOTed and never profiled
+                    // for profile guided compilation.
                     installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
-                            dexoptNeeded, 0 /*dexFlags*/);
+                            dexoptNeeded, 0 /*dexFlags*/, null /*volumeUuid*/,
+                            false /*useProfiles*/);
                 }
             }
         } catch (IOException | InstallerException e) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index cea9867..36009dc 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -17,6 +17,7 @@
 package com.android.internal.policy;
 
 import com.android.internal.R;
+import com.android.internal.policy.PhoneWindow.PanelFeatureState;
 import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback;
 import com.android.internal.view.FloatingActionMode;
 import com.android.internal.view.RootViewSurfaceTaker;
@@ -28,10 +29,13 @@
 import com.android.internal.widget.DecorCaptionView;
 import com.android.internal.widget.FloatingToolbar;
 
+import java.util.List;
+
 import android.animation.Animator;
 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;
@@ -48,6 +52,7 @@
 import android.view.Gravity;
 import android.view.InputQueue;
 import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -85,11 +90,14 @@
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
 
 /** @hide */
 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.
@@ -570,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(
@@ -592,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(
@@ -636,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);
@@ -1586,7 +1597,9 @@
         }
     }
 
-    void onConfigurationChanged() {
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
         int workspaceId = getStackId();
         if (mStackId != workspaceId) {
             mStackId = workspaceId;
@@ -1943,19 +1956,49 @@
         }
     }
 
-    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,
                 res.getConfiguration().screenWidthDp, res.getDisplayMetrics());
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> list) {
+        final PanelFeatureState st = mWindow.getPanelState(FEATURE_OPTIONS_PANEL, false);
+        if (!mWindow.isDestroyed() && st != null && mWindow.getCallback() != null) {
+            try {
+                mWindow.getCallback().onProvideKeyboardShortcuts(list, st.menu);
+            } catch (AbstractMethodError e) {
+                // We run into this if the app is using supportlib.
+            }
+        }
+    }
+
+    @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/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index e79f1b8..59a1e4a 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -62,6 +62,7 @@
 
     private final SnapTarget mDismissStartTarget;
     private final SnapTarget mDismissEndTarget;
+    private final SnapTarget mMiddleTarget;
 
     public DividerSnapAlgorithm(Resources res, float minFlingVelocityPxPerSecond,
             int displayWidth, int displayHeight, int dividerSize, boolean isHorizontalDivision,
@@ -80,6 +81,7 @@
         mLastSplitTarget = mTargets.get(mTargets.size() - 2);
         mDismissStartTarget = mTargets.get(0);
         mDismissEndTarget = mTargets.get(mTargets.size() - 1);
+        mMiddleTarget = mTargets.get(mTargets.size() / 2);
     }
 
     public SnapTarget calculateSnapTarget(int position, float velocity) {
@@ -207,12 +209,12 @@
     }
 
     private void addMiddleTarget(boolean isHorizontalDivision) {
-        int start = isHorizontalDivision ? mInsets.top : mInsets.left;
-        int end = isHorizontalDivision
-                ? mDisplayHeight - mInsets.bottom
-                : mDisplayWidth - mInsets.right;
-        mTargets.add(new SnapTarget(start + (end - start) / 2 - mDividerSize / 2,
-                SnapTarget.FLAG_NONE));
+        mTargets.add(new SnapTarget(DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
+                mInsets, mDisplayWidth, mDisplayHeight, mDividerSize), SnapTarget.FLAG_NONE));
+    }
+
+    public SnapTarget getMiddleTarget() {
+        return mMiddleTarget;
     }
 
     /**
diff --git a/core/java/com/android/internal/policy/DockedDividerUtils.java b/core/java/com/android/internal/policy/DockedDividerUtils.java
index 25a060e..f7f5f15 100644
--- a/core/java/com/android/internal/policy/DockedDividerUtils.java
+++ b/core/java/com/android/internal/policy/DockedDividerUtils.java
@@ -19,6 +19,11 @@
 import android.graphics.Rect;
 import android.view.WindowManager;
 
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
+
 /**
  * Utility functions for docked stack divider used by both window manager and System UI.
  *
@@ -43,17 +48,17 @@
                 outRect.top = position + dividerSize;
                 break;
         }
-        if (outRect.left > outRect.right) {
-            outRect.left = outRect.right;
+        if (outRect.left >= outRect.right) {
+            outRect.left = outRect.right - 1;
         }
-        if (outRect.top > outRect.bottom) {
-            outRect.top = outRect.bottom;
+        if (outRect.top >= outRect.bottom) {
+            outRect.top = outRect.bottom - 1;
         }
-        if (outRect.right < outRect.left) {
-            outRect.right = outRect.left;
+        if (outRect.right <= outRect.left) {
+            outRect.right = outRect.left + 1;
         }
-        if (outRect.bottom < outRect.top) {
-            outRect.bottom = outRect.top;
+        if (outRect.bottom <= outRect.top) {
+            outRect.bottom = outRect.top + 1;
         }
     }
 
@@ -71,4 +76,45 @@
                 return 0;
         }
     }
+
+    public static int calculateMiddlePosition(boolean isHorizontalDivision, Rect insets,
+            int displayWidth, int displayHeight, int dividerSize) {
+        int start = isHorizontalDivision ? insets.top : insets.left;
+        int end = isHorizontalDivision
+                ? displayHeight - insets.bottom
+                : displayWidth - insets.right;
+        return start + (end - start) / 2 - dividerSize / 2;
+    }
+
+    public static int getDockSideFromCreatedMode(boolean dockOnTopOrLeft,
+            boolean isHorizontalDivision) {
+        if (dockOnTopOrLeft) {
+            if (isHorizontalDivision) {
+                return DOCKED_TOP;
+            } else {
+                return DOCKED_LEFT;
+            }
+        } else {
+            if (isHorizontalDivision) {
+                return DOCKED_BOTTOM;
+            } else {
+                return DOCKED_RIGHT;
+            }
+        }
+    }
+
+    public static int invertDockSide(int dockSide) {
+        switch (dockSide) {
+            case WindowManager.DOCKED_LEFT:
+                return WindowManager.DOCKED_RIGHT;
+            case WindowManager.DOCKED_TOP:
+                return WindowManager.DOCKED_BOTTOM;
+            case WindowManager.DOCKED_RIGHT:
+                return WindowManager.DOCKED_LEFT;
+            case WindowManager.DOCKED_BOTTOM:
+                return WindowManager.DOCKED_TOP;
+            default:
+                return WindowManager.DOCKED_INVALID;
+        }
+    }
 }
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index b4c4ef5..19ed11a 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -672,15 +672,19 @@
                 }
             }
         }
-        if (mDecor != null) {
-            mDecor.onConfigurationChanged();
-        }
     }
 
     @Override
     public void onMultiWindowModeChanged() {
         if (mDecor != null) {
-            mDecor.onConfigurationChanged();
+            mDecor.onConfigurationChanged(getContext().getResources().getConfiguration());
+        }
+    }
+
+    @Override
+    public void reportActivityRelaunched() {
+        if (mDecor != null && mDecor.getViewRootImpl() != null) {
+            mDecor.getViewRootImpl().reportActivityRelaunched();
         }
     }
 
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index b692a18..381e71f 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -16,6 +16,10 @@
 
 package com.android.internal.util;
 
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.text.TextUtils;
+
 import java.util.Collection;
 
 /**
@@ -31,6 +35,22 @@
     }
 
     /**
+     * Ensures that an string reference passed as a parameter to the calling
+     * method is not empty.
+     *
+     * @param string an string reference
+     * @return the string reference that was validated
+     * @throws IllegalArgumentException if {@code string} is empty
+     */
+    public static @NonNull String checkStringNotEmpty(final String string,
+            final Object errorMessage) {
+        if (TextUtils.isEmpty(string)) {
+            throw new IllegalArgumentException(String.valueOf(errorMessage));
+        }
+        return string;
+    }
+
+    /**
      * Ensures that an object reference passed as a parameter to the calling
      * method is not null.
      *
@@ -38,7 +58,7 @@
      * @return the non-null reference that was validated
      * @throws NullPointerException if {@code reference} is null
      */
-    public static <T> T checkNotNull(final T reference) {
+    public static @NonNull <T> T checkNotNull(final T reference) {
         if (reference == null) {
             throw new NullPointerException();
         }
@@ -55,7 +75,7 @@
      * @return the non-null reference that was validated
      * @throws NullPointerException if {@code reference} is null
      */
-    public static <T> T checkNotNull(final T reference, final Object errorMessage) {
+    public static @NonNull <T> T checkNotNull(final T reference, final Object errorMessage) {
         if (reference == null) {
             throw new NullPointerException(String.valueOf(errorMessage));
         }
@@ -95,7 +115,8 @@
      * @return the validated numeric value
      * @throws IllegalArgumentException if {@code value} was negative
      */
-    public static int checkArgumentNonnegative(final int value, final String errorMessage) {
+    public static @IntRange(from = 0) int checkArgumentNonnegative(final int value,
+            final String errorMessage) {
         if (value < 0) {
             throw new IllegalArgumentException(errorMessage);
         }
@@ -218,6 +239,33 @@
     }
 
     /**
+     * Ensures that the argument long value is within the inclusive range.
+     *
+     * @param value a long value
+     * @param lower the lower endpoint of the inclusive range
+     * @param upper the upper endpoint of the inclusive range
+     * @param valueName the name of the argument to use if the check fails
+     *
+     * @return the validated long value
+     *
+     * @throws IllegalArgumentException if {@code value} was not within the range
+     */
+    public static long checkArgumentInRange(long value, long lower, long upper,
+            String valueName) {
+        if (value < lower) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s is out of range of [%d, %d] (too low)", valueName, lower, upper));
+        } else if (value > upper) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "%s is out of range of [%d, %d] (too high)", valueName, lower, upper));
+        }
+
+        return value;
+    }
+
+    /**
      * Ensures that the array is not {@code null}, and none of its elements are {@code null}.
      *
      * @param value an array of boxed objects
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 8699843..aa4b564c 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -25,6 +25,8 @@
 import android.view.IWindow;
 import android.view.IWindowSession;
 
+import com.android.internal.os.IResultReceiver;
+
 public class BaseIWindow extends IWindow.Stub {
     private IWindowSession mSession;
     public int mSeq;
@@ -103,4 +105,8 @@
     @Override
     public void dispatchWindowShown() {
     }
+
+    @Override
+    public void requestAppKeyboardShortcuts(IResultReceiver receiver) {
+    }
 }
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index 85ec29c..3be15f3 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -30,7 +30,7 @@
 
 import java.lang.ref.WeakReference;
 
-public class IInputConnectionWrapper extends IInputContext.Stub {
+public abstract class IInputConnectionWrapper extends IInputContext.Stub {
     static final String TAG = "IInputConnectionWrapper";
 
     private static final int DO_GET_TEXT_AFTER_CURSOR = 10;
@@ -49,6 +49,7 @@
     private static final int DO_FINISH_COMPOSING_TEXT = 65;
     private static final int DO_SEND_KEY_EVENT = 70;
     private static final int DO_DELETE_SURROUNDING_TEXT = 80;
+    private static final int DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 81;
     private static final int DO_BEGIN_BATCH_EDIT = 90;
     private static final int DO_END_BATCH_EDIT = 95;
     private static final int DO_REPORT_FULLSCREEN_MODE = 100;
@@ -80,15 +81,25 @@
     }
     
     public IInputConnectionWrapper(Looper mainLooper, InputConnection conn) {
-        mInputConnection = new WeakReference<InputConnection>(conn);
+        mInputConnection = new WeakReference<>(conn);
         mMainLooper = mainLooper;
         mH = new MyHandler(mMainLooper);
     }
 
-    public boolean isActive() {
-        return true;
-    }
-    
+    abstract protected boolean isActive();
+
+    /**
+     * Called when the user took some actions that should be taken into consideration to update the
+     * LRU list for input method rotation.
+     */
+    abstract protected void onUserAction();
+
+    /**
+     * Called when the input method started or stopped full-screen mode.
+     *
+     */
+    abstract protected void onReportFullscreenMode(boolean enabled);
+
     public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
         dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
     }
@@ -155,9 +166,14 @@
         dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
     }
 
-    public void deleteSurroundingText(int leftLength, int rightLength) {
+    public void deleteSurroundingText(int beforeLength, int afterLength) {
         dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
-            leftLength, rightLength));
+                beforeLength, afterLength));
+    }
+
+    public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
+        dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
+                beforeLength, afterLength));
     }
 
     public void beginBatchEdit() {
@@ -284,6 +300,7 @@
                     return;
                 }
                 ic.commitText((CharSequence)msg.obj, msg.arg1);
+                onUserAction();
                 return;
             }
             case DO_SET_SELECTION: {
@@ -338,6 +355,7 @@
                     return;
                 }
                 ic.setComposingText((CharSequence)msg.obj, msg.arg1);
+                onUserAction();
                 return;
             }
             case DO_SET_COMPOSING_REGION: {
@@ -369,6 +387,7 @@
                     return;
                 }
                 ic.sendKeyEvent((KeyEvent)msg.obj);
+                onUserAction();
                 return;
             }
             case DO_CLEAR_META_KEY_STATES: {
@@ -389,6 +408,15 @@
                 ic.deleteSurroundingText(msg.arg1, msg.arg2);
                 return;
             }
+            case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
+                InputConnection ic = mInputConnection.get();
+                if (ic == null || !isActive()) {
+                    Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
+                    return;
+                }
+                ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
+                return;
+            }
             case DO_BEGIN_BATCH_EDIT: {
                 InputConnection ic = mInputConnection.get();
                 if (ic == null || !isActive()) {
@@ -413,7 +441,9 @@
                     Log.w(TAG, "reportFullscreenMode on inexistent InputConnection");
                     return;
                 }
-                ic.reportFullscreenMode(msg.arg1 == 1);
+                final boolean enabled = msg.arg1 == 1;
+                ic.reportFullscreenMode(enabled);
+                onReportFullscreenMode(enabled);
                 return;
             }
             case DO_PERFORM_PRIVATE_COMMAND: {
@@ -454,7 +484,7 @@
     Message obtainMessageII(int what, int arg1, int arg2) {
         return mH.obtainMessage(what, arg1, arg2);
     }
-    
+
     Message obtainMessageO(int what, Object arg1) {
         return mH.obtainMessage(what, 0, 0, arg1);
     }
diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index fd2b513..f7ec420 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -38,8 +38,9 @@
     
     void getExtractedText(in ExtractedTextRequest request, int flags, int seq,
             IInputContextCallback callback);
-    
-    void deleteSurroundingText(int leftLength, int rightLength);
+
+    void deleteSurroundingText(int beforeLength, int afterLength);
+    void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength);
 
     void setComposingText(CharSequence text, int newCursorPosition);
 
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index 7dc927f..94790c1 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -400,7 +400,7 @@
             return false;
         }
     }
-    
+
     public boolean deleteSurroundingText(int beforeLength, int afterLength) {
         try {
             mIInputContext.deleteSurroundingText(beforeLength, afterLength);
@@ -410,6 +410,15 @@
         }
     }
 
+    public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
+        try {
+            mIInputContext.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
+            return true;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     public boolean reportFullscreenMode(boolean enabled) {
         try {
             mIInputContext.reportFullscreenMode(enabled);
diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
index 320de90..a502fcc 100644
--- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
@@ -362,6 +362,7 @@
 
         final int x;
         final int y;
+        final Rect epicenterBounds;
         if (parentView != null) {
             // This menu is a cascading submenu anchored to a parent view.
             popupWindow.setTouchModal(false);
@@ -396,13 +397,16 @@
             }
 
             y = parentOffsetTop;
+            epicenterBounds = null;
         } else {
             x = mInitXOffset;
             y = mInitYOffset;
+            epicenterBounds = getEpicenterBounds();
         }
 
         popupWindow.setHorizontalOffset(x);
         popupWindow.setVerticalOffset(y);
+        popupWindow.setEpicenterBounds(epicenterBounds);
 
         final CascadingMenuInfo menuInfo = new CascadingMenuInfo(popupWindow, menu, mLastPosition);
         mShowingMenus.add(menuInfo);
diff --git a/core/java/com/android/internal/view/menu/MenuPopup.java b/core/java/com/android/internal/view/menu/MenuPopup.java
index b151f34..42b1a56 100644
--- a/core/java/com/android/internal/view/menu/MenuPopup.java
+++ b/core/java/com/android/internal/view/menu/MenuPopup.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.graphics.Rect;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.MeasureSpec;
@@ -37,6 +38,7 @@
  */
 public abstract class MenuPopup implements ShowableListMenu, MenuPresenter,
         AdapterView.OnItemClickListener {
+    private Rect mEpicenterBounds;
 
     public abstract void setForceShowIcon(boolean forceShow);
 
@@ -60,6 +62,23 @@
     public abstract void setVerticalOffset(int y);
 
     /**
+     * Specifies the anchor-relative bounds of the popup's transition
+     * epicenter.
+     *
+     * @param bounds anchor-relative bounds
+     */
+    public void setEpicenterBounds(Rect bounds) {
+        mEpicenterBounds = bounds;
+    }
+
+    /**
+     * @return anchor-relative bounds of the popup's transition epicenter
+     */
+    public Rect getEpicenterBounds() {
+        return mEpicenterBounds;
+    }
+
+    /**
      * Set whether a title entry should be shown in the popup menu (if a title exists for the
      * menu).
      *
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 044ee6e..1f1e594 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -23,6 +23,8 @@
 import android.annotation.Nullable;
 import android.annotation.StyleRes;
 import android.content.Context;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
 import android.view.Gravity;
 import android.view.View;
 import android.widget.PopupWindow.OnDismissListener;
@@ -31,6 +33,8 @@
  * Presents a menu as a small, simple popup anchored to another view.
  */
 public class MenuPopupHelper implements MenuHelper {
+    private static final int TOUCH_EPICENTER_SIZE_DP = 48;
+
     private final Context mContext;
 
     // Immutable cached popup menu properties.
@@ -163,6 +167,11 @@
      * Shows the popup menu and makes a best-effort to anchor it to the
      * specified (x,y) coordinate relative to the anchor view.
      * <p>
+     * Additionally, the popup's transition epicenter (see
+     * {@link android.widget.PopupWindow#setEpicenterBounds(Rect)} will be
+     * centered on the specified coordinate, rather than using the bounds of
+     * the anchor view.
+     * <p>
      * If the popup's resolved gravity is {@link Gravity#LEFT}, this will
      * display the popup with its top-left corner at (x,y) relative to the
      * anchor view. If the resolved gravity is {@link Gravity#RIGHT}, the
@@ -222,8 +231,11 @@
         return popup;
     }
 
-    private void showPopup(int xOffset, int yOffset, boolean resolveOffsets, boolean showTitle) {
-        if (resolveOffsets) {
+    private void showPopup(int xOffset, int yOffset, boolean useOffsets, boolean showTitle) {
+        final MenuPopup popup = getPopup();
+        popup.setShowTitle(showTitle);
+
+        if (useOffsets) {
             // If the resolved drop-down gravity is RIGHT, the popup's right
             // edge will be aligned with the anchor view. Adjust by the anchor
             // width such that the top-right corner is at the X offset.
@@ -232,12 +244,21 @@
             if (hgrav == Gravity.RIGHT) {
                 xOffset -= mAnchorView.getWidth();
             }
+
+            popup.setHorizontalOffset(xOffset);
+            popup.setVerticalOffset(yOffset);
+
+            // Set the transition epicenter to be roughly finger (or mouse
+            // cursor) sized and centered around the offset position. This
+            // will give the appearance that the window is emerging from
+            // the touch point.
+            final float density = mContext.getResources().getDisplayMetrics().density;
+            final int halfSize = (int) (TOUCH_EPICENTER_SIZE_DP * density / 2);
+            final Rect epicenter = new Rect(xOffset - halfSize, yOffset - halfSize,
+                    xOffset + halfSize, yOffset + halfSize);
+            popup.setEpicenterBounds(epicenter);
         }
 
-        final MenuPopup popup = getPopup();
-        popup.setHorizontalOffset(xOffset);
-        popup.setVerticalOffset(yOffset);
-        popup.setShowTitle(showTitle);
         popup.show();
     }
 
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index c2adc42..2d4baa2 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.internal.view.menu;
 
 import android.content.Context;
@@ -7,7 +23,6 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.View.OnKeyListener;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
@@ -30,7 +45,7 @@
         MenuPresenter, OnKeyListener {
 
     private final Context mContext;
-    private final LayoutInflater mInflater;
+
     private final MenuBuilder mMenu;
     private final MenuAdapter mAdapter;
     private final boolean mOverflowOnly;
@@ -79,8 +94,6 @@
     private Callback mPresenterCallback;
     private ViewTreeObserver mTreeObserver;
 
-    private ViewGroup mMeasureParent;
-
     /** Whether the popup has been dismissed. Once dismissed, it cannot be opened again. */
     private boolean mWasDismissed;
 
@@ -99,10 +112,10 @@
     public StandardMenuPopup(Context context, MenuBuilder menu, View anchorView, int popupStyleAttr,
             int popupStyleRes, boolean overflowOnly) {
         mContext = Preconditions.checkNotNull(context);
-        mInflater = LayoutInflater.from(context);
         mMenu = menu;
         mOverflowOnly = overflowOnly;
-        mAdapter = new MenuAdapter(menu, mInflater, mOverflowOnly);
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        mAdapter = new MenuAdapter(menu, inflater, mOverflowOnly);
         mPopupStyleAttr = popupStyleAttr;
         mPopupStyleRes = popupStyleRes;
 
@@ -155,8 +168,7 @@
         mPopup.setDropDownGravity(mDropDownGravity);
 
         if (!mHasContentWidth) {
-            mContentWidth = measureIndividualMenuWidth(
-                    mAdapter, mMeasureParent, mContext, mPopupMaxWidth);
+            mContentWidth = measureIndividualMenuWidth(mAdapter, null, mContext, mPopupMaxWidth);
             mHasContentWidth = true;
         }
 
@@ -164,6 +176,7 @@
         mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
         mPopup.setHorizontalOffset(mXOffset);
         mPopup.setVerticalOffset(mYOffset);
+        mPopup.setEpicenterBounds(getEpicenterBounds());
         mPopup.show();
 
         ListView listView = mPopup.getListView();
@@ -177,7 +190,9 @@
                             false);
             TextView titleView = (TextView) titleItemView.findViewById(
                     com.android.internal.R.id.title);
-            titleView.setText(mMenu.getHeaderTitle());
+            if (titleView != null) {
+                titleView.setText(mMenu.getHeaderTitle());
+            }
             titleItemView.setEnabled(false);
             listView.addHeaderView(titleItemView, null, false);
 
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e38d82f..4e8f19c 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -24,6 +24,7 @@
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.IBinder;
@@ -34,6 +35,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.storage.IMountService;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
@@ -135,6 +137,8 @@
 
     private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
 
+    private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
+
     // Maximum allowed number of repeated or ordered characters in a sequence before we'll
     // consider it a complex PIN/password.
     public static final int MAX_ALLOWED_SEQUENCE = 3;
@@ -143,6 +147,7 @@
     private final ContentResolver mContentResolver;
     private DevicePolicyManager mDevicePolicyManager;
     private ILockSettings mLockSettingsService;
+    private UserManager mUserManager;
 
 
     public static final class RequestThrottledException extends Exception {
@@ -173,6 +178,13 @@
         return mDevicePolicyManager;
     }
 
+    private UserManager getUserManager() {
+        if (mUserManager == null) {
+            mUserManager = UserManager.get(mContext);
+        }
+        return mUserManager;
+    }
+
     private TrustManager getTrustManager() {
         TrustManager trust = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
         if (trust == null) {
@@ -866,6 +878,39 @@
     }
 
     /**
+     * Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op
+     * for user handles that do not belong to a managed profile.
+     */
+    public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled) {
+        UserInfo info = getUserManager().getUserInfo(userHandle);
+        if (info.isManagedProfile()) {
+            setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userHandle);
+        }
+    }
+
+    /**
+     * Retrieves whether the Separate Profile Challenge is enabled for this {@param userHandle}.
+     */
+    public boolean isSeparateProfileChallengeEnabled(int userHandle) {
+        UserInfo info = getUserManager().getUserInfo(userHandle);
+        if (info == null || !info.isManagedProfile()) {
+            return false;
+        }
+        return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userHandle);
+    }
+
+    /**
+     * Retrieves whether the current DPM allows use of the Profile Challenge.
+     */
+    public boolean isSeparateProfileChallengeAllowed(int userHandle) {
+        UserInfo info = getUserManager().getUserInfo(userHandle);
+        if (info == null || !info.isManagedProfile()) {
+            return false;
+        }
+        return getDevicePolicyManager().isSeparateProfileChallengeAllowed(userHandle);
+    }
+
+    /**
      * Deserialize a pattern.
      * @param string The pattern serialized with {@link #patternToString}
      * @return The pattern.
@@ -1288,10 +1333,6 @@
         }
     }
 
-    public static boolean isSeparateWorkChallengeEnabled() {
-        return StorageManager.isFileBasedEncryptionEnabled();
-    }
-
     public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
         try {
             getLockSettings().registerStrongAuthTracker(strongAuthTracker.mStub);
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/com/android/server/backup/PermissionBackupHelper.java b/core/java/com/android/server/backup/PermissionBackupHelper.java
new file mode 100644
index 0000000..ff0e63d
--- /dev/null
+++ b/core/java/com/android/server/backup/PermissionBackupHelper.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup;
+
+import android.app.AppGlobals;
+import android.app.backup.BlobBackupHelper;
+import android.content.pm.IPackageManager;
+import android.os.UserHandle;
+import android.util.Slog;
+
+public class PermissionBackupHelper extends BlobBackupHelper {
+    private static final String TAG = "PermissionBackup";
+    private static final boolean DEBUG = false;
+
+    // current schema of the backup state blob
+    private static final int STATE_VERSION = 1;
+
+    // key under which the permission-grant state blob is committed to backup
+    private static final String KEY_PERMISSIONS = "permissions";
+
+    public PermissionBackupHelper() {
+        super(STATE_VERSION, KEY_PERMISSIONS);
+    }
+
+    @Override
+    protected byte[] getBackupPayload(String key) {
+        IPackageManager pm = AppGlobals.getPackageManager();
+        if (DEBUG) {
+            Slog.d(TAG, "Handling backup of " + key);
+        }
+        try {
+            switch (key) {
+                case KEY_PERMISSIONS:
+                    return pm.getPermissionGrantBackup(UserHandle.USER_SYSTEM);
+
+                default:
+                    Slog.w(TAG, "Unexpected backup key " + key);
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Unable to store payload " + key);
+        }
+        return null;
+    }
+
+    @Override
+    protected void applyRestoredPayload(String key, byte[] payload) {
+        IPackageManager pm = AppGlobals.getPackageManager();
+        if (DEBUG) {
+            Slog.d(TAG, "Handling restore of " + key);
+        }
+        try {
+            switch (key) {
+                case KEY_PERMISSIONS:
+                    pm.restorePermissionGrants(payload, UserHandle.USER_SYSTEM);
+                    break;
+
+                default:
+                    Slog.w(TAG, "Unexpected restore key " + key);
+            }
+        } catch (Exception e) {
+            Slog.w(TAG, "Unable to restore key " + key);
+        }
+    }
+}
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index 234815f..3f76e13 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -46,6 +46,7 @@
     private static final String SYNC_SETTINGS_HELPER = "account_sync_settings";
     private static final String PREFERRED_HELPER = "preferred_activities";
     private static final String NOTIFICATION_HELPER = "notifications";
+    private static final String PERMISSION_HELPER = "permissions";
 
     // These paths must match what the WallpaperManagerService uses.  The leaf *_FILENAME
     // are also used in the full-backup file format, so must not change unless steps are
@@ -94,6 +95,7 @@
         addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
+        addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
 
         super.onBackup(oldState, data, newState);
     }
@@ -128,6 +130,7 @@
         addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
+        addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
 
         try {
             super.onRestore(data, appVersionCode, newState);
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 fc1ba44..644ecc6 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -34,6 +34,7 @@
     com_google_android_gles_jni_EGLImpl.cpp \
     com_google_android_gles_jni_GLImpl.cpp.arm \
     android_app_NativeActivity.cpp \
+    android_auditing_SecurityLog.cpp \
     android_opengl_EGL14.cpp \
     android_opengl_EGLExt.cpp \
     android_opengl_GLES10.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 63f193d..321440c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -108,6 +108,7 @@
  * JNI-based registration functions.  Note these are properly contained in
  * namespace android.
  */
+extern int register_android_auditing_SecurityLog(JNIEnv* env);
 extern int register_android_content_AssetManager(JNIEnv* env);
 extern int register_android_util_EventLog(JNIEnv* env);
 extern int register_android_util_Log(JNIEnv* env);
@@ -586,6 +587,7 @@
     char jitmaxsizeOptsBuf[sizeof("-Xjitmaxsize:")-1 + PROPERTY_VALUE_MAX];
     char jitinitialsizeOptsBuf[sizeof("-Xjitinitialsize:")-1 + PROPERTY_VALUE_MAX];
     char jitthresholdOptsBuf[sizeof("-Xjitthreshold:")-1 + PROPERTY_VALUE_MAX];
+    char useJitProfilesOptsBuf[sizeof("-Xjitsaveprofilinginfo:")-1 + PROPERTY_VALUE_MAX];
     char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
     char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
     char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
@@ -691,6 +693,10 @@
     parseRuntimeOption("dalvik.vm.jitmaxsize", jitmaxsizeOptsBuf, "-Xjitmaxsize:");
     parseRuntimeOption("dalvik.vm.jitinitialsize", jitinitialsizeOptsBuf, "-Xjitinitialsize:");
     parseRuntimeOption("dalvik.vm.jitthreshold", jitthresholdOptsBuf, "-Xjitthreshold:");
+    property_get("dalvik.vm.usejitprofiles", useJitProfilesOptsBuf, "");
+    if (strcmp(useJitProfilesOptsBuf, "true") == 0) {
+        addOption("-Xjitsaveprofilinginfo");
+    }
 
     property_get("ro.config.low_ram", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
@@ -1244,6 +1250,7 @@
     REG_JNI(register_android_util_EventLog),
     REG_JNI(register_android_util_Log),
     REG_JNI(register_android_util_PathParser),
+    REG_JNI(register_android_auditing_SecurityLog),
     REG_JNI(register_android_content_AssetManager),
     REG_JNI(register_android_content_StringBlock),
     REG_JNI(register_android_content_XmlBlock),
@@ -1257,6 +1264,7 @@
     REG_JNI(register_android_os_Binder),
     REG_JNI(register_android_os_Parcel),
     REG_JNI(register_android_nio_utils),
+    REG_JNI(register_android_graphics_Canvas),
     REG_JNI(register_android_graphics_Graphics),
     REG_JNI(register_android_view_DisplayEventReceiver),
     REG_JNI(register_android_view_RenderNode),
@@ -1289,7 +1297,6 @@
     REG_JNI(register_android_graphics_BitmapRegionDecoder),
     REG_JNI(register_android_graphics_Camera),
     REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
-    REG_JNI(register_android_graphics_Canvas),
     REG_JNI(register_android_graphics_CanvasProperty),
     REG_JNI(register_android_graphics_ColorFilter),
     REG_JNI(register_android_graphics_DrawFilter),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index a805b6d..80ccb61 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -774,11 +774,14 @@
     return ret;
 }
 
-static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) {
-    LocalScopedBitmap bitmap(bitmapHandle);
+static void Bitmap_destruct(Bitmap* bitmap) {
     bitmap->detachFromJava();
 }
 
+static jlong Bitmap_getNativeFinalizer(JNIEnv*, jobject) {
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Bitmap_destruct));
+}
+
 static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
     LocalScopedBitmap bitmap(bitmapHandle);
     bitmap->freePixels();
@@ -1357,7 +1360,7 @@
         (void*)Bitmap_copy },
     {   "nativeCopyAshmem",         "(J)Landroid/graphics/Bitmap;",
         (void*)Bitmap_copyAshmem },
-    {   "nativeDestructor",         "(J)V", (void*)Bitmap_destructor },
+    {   "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer },
     {   "nativeRecycle",            "(J)Z", (void*)Bitmap_recycle },
     {   "nativeReconfigure",        "(JIIIIZ)V", (void*)Bitmap_reconfigure },
     {   "nativeCompress",           "(JIILjava/io/OutputStream;[B)Z",
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 83fd073..1a86e5f 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -42,7 +42,7 @@
     }
 
     static jlong CreateLightingFilter(JNIEnv* env, jobject, jint mul, jint add) {
-        return reinterpret_cast<jlong>(SkColorFilter::CreateLightingFilter(mul, add));
+        return reinterpret_cast<jlong>(SkColorMatrixFilter::CreateLightingFilter(mul, add));
     }
 
     static jlong CreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) {
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 0a25a0a..98f8ce3 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -76,9 +76,12 @@
         AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
     };
 
-    static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
-        Paint* obj = reinterpret_cast<Paint*>(objHandle);
-        delete obj;
+    static void deletePaint(Paint* paint) {
+        delete paint;
+    }
+
+    static jlong getNativeFinalizer(JNIEnv*, jobject) {
+        return static_cast<jlong>(reinterpret_cast<uintptr_t>(&deletePaint));
     }
 
     static jlong init(JNIEnv* env, jobject) {
@@ -863,7 +866,7 @@
 }; // namespace PaintGlue
 
 static const JNINativeMethod methods[] = {
-    {"nFinalizer", "(J)V", (void*) PaintGlue::finalizer},
+    {"nGetNativeFinalizer", "()J", (void*) PaintGlue::getNativeFinalizer},
     {"nInit","()J", (void*) PaintGlue::init},
     {"nInitWithPaint","(J)J", (void*) PaintGlue::initWithPaint},
 
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index fda0ffa..2507e4d 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -60,6 +60,27 @@
     // as all the data needed is contained within the newly created LocalMatrixShader.
     SkASSERT(shaderHandle);
     SkAutoTUnref<SkShader> currentShader(reinterpret_cast<SkShader*>(shaderHandle));
+
+    // Attempt to peel off an existing proxy shader and get the proxy's matrix. If
+    // the proxy existed and it's matrix equals the desired matrix then just return
+    // the proxy, otherwise replace it with a new proxy containing the desired matrix.
+    //
+    // refAsALocalMatrixShader(): if the shader contains a proxy then it unwraps the proxy
+    //                            returning both the underlying shader and the proxy's matrix.
+    // newWithLocalMatrix(): will return a proxy shader that wraps the provided shader and
+    //                       concats the provided local matrix with the shader's matrix.
+    //
+    // WARNING: This proxy replacement only behaves like a setter because the Java
+    //          API enforces that all local matrices are set using this call and
+    //          not passed to the constructor of the Shader.
+    SkMatrix proxyMatrix;
+    SkAutoTUnref<SkShader> baseShader(currentShader->refAsALocalMatrixShader(&proxyMatrix));
+    if (baseShader.get()) {
+        if (proxyMatrix == *matrix) {
+            return reinterpret_cast<jlong>(currentShader.detach());
+        }
+        return reinterpret_cast<jlong>(baseShader->newWithLocalMatrix(*matrix));
+    }
     return reinterpret_cast<jlong>(currentShader->newWithLocalMatrix(*matrix));
 }
 
diff --git a/core/jni/android_auditing_SecurityLog.cpp b/core/jni/android_auditing_SecurityLog.cpp
new file mode 100644
index 0000000..78f04cd
--- /dev/null
+++ b/core/jni/android_auditing_SecurityLog.cpp
@@ -0,0 +1,312 @@
+/*
+ * 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 <fcntl.h>
+
+#include "JNIHelp.h"
+#include "core_jni_helpers.h"
+#include "jni.h"
+#include "log/logger.h"
+
+// The size of the tag number comes out of the payload size.
+#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
+
+namespace android {
+
+static jclass gCollectionClass;
+static jmethodID gCollectionAddID;
+
+static jclass gEventClass;
+static jmethodID gEventInitID;
+
+static jclass gIntegerClass;
+static jfieldID gIntegerValueID;
+
+static jclass gLongClass;
+static jfieldID gLongValueID;
+
+static jclass gFloatClass;
+static jfieldID gFloatValueID;
+
+static jclass gStringClass;
+
+
+static jboolean android_auditing_SecurityLog_isLoggingEnabled(JNIEnv* env,
+                                                    jobject /* clazz */) {
+    return (bool)__android_log_security();
+}
+
+static jint android_auditing_SecurityLog_writeEvent_String(JNIEnv* env,
+                                                    jobject /* clazz */,
+                                                    jint tag, jstring value) {
+    uint8_t buf[MAX_EVENT_PAYLOAD];
+
+    // Don't throw NPE -- I feel like it's sort of mean for a logging function
+    // to be all crashy if you pass in NULL -- but make the NULL value explicit.
+    const char *str = value != NULL ? env->GetStringUTFChars(value, NULL) : "NULL";
+    uint32_t len = strlen(str);
+    size_t max = sizeof(buf) - sizeof(len) - 2;  // Type byte, final newline
+    if (len > max) len = max;
+
+    buf[0] = EVENT_TYPE_STRING;
+    memcpy(&buf[1], &len, sizeof(len));
+    memcpy(&buf[1 + sizeof(len)], str, len);
+    buf[1 + sizeof(len) + len] = '\n';
+
+    if (value != NULL) env->ReleaseStringUTFChars(value, str);
+    return __android_log_security_bwrite(tag, buf, 2 + sizeof(len) + len);
+}
+
+static jint android_auditing_SecurityLog_writeEvent_Array(JNIEnv* env, jobject clazz,
+                                                   jint tag, jobjectArray value) {
+    if (value == NULL) {
+        return android_auditing_SecurityLog_writeEvent_String(env, clazz, tag, NULL);
+    }
+
+    uint8_t buf[MAX_EVENT_PAYLOAD];
+    const size_t max = sizeof(buf) - 1;  // leave room for final newline
+    size_t pos = 2;  // Save room for type tag & array count
+
+    jsize copied = 0, num = env->GetArrayLength(value);
+    for (; copied < num && copied < 255; ++copied) {
+        jobject item = env->GetObjectArrayElement(value, copied);
+        if (item == NULL || env->IsInstanceOf(item, gStringClass)) {
+            if (pos + 1 + sizeof(jint) > max) break;
+            const char *str = item != NULL ? env->GetStringUTFChars((jstring) item, NULL) : "NULL";
+            jint len = strlen(str);
+            if (pos + 1 + sizeof(len) + len > max) len = max - pos - 1 - sizeof(len);
+            buf[pos++] = EVENT_TYPE_STRING;
+            memcpy(&buf[pos], &len, sizeof(len));
+            memcpy(&buf[pos + sizeof(len)], str, len);
+            pos += sizeof(len) + len;
+            if (item != NULL) env->ReleaseStringUTFChars((jstring) item, str);
+        } else if (env->IsInstanceOf(item, gIntegerClass)) {
+            jint intVal = env->GetIntField(item, gIntegerValueID);
+            if (pos + 1 + sizeof(intVal) > max) break;
+            buf[pos++] = EVENT_TYPE_INT;
+            memcpy(&buf[pos], &intVal, sizeof(intVal));
+            pos += sizeof(intVal);
+        } else if (env->IsInstanceOf(item, gLongClass)) {
+            jlong longVal = env->GetLongField(item, gLongValueID);
+            if (pos + 1 + sizeof(longVal) > max) break;
+            buf[pos++] = EVENT_TYPE_LONG;
+            memcpy(&buf[pos], &longVal, sizeof(longVal));
+            pos += sizeof(longVal);
+        } else if (env->IsInstanceOf(item, gFloatClass)) {
+            jfloat floatVal = env->GetFloatField(item, gFloatValueID);
+            if (pos + 1 + sizeof(floatVal) > max) break;
+            buf[pos++] = EVENT_TYPE_FLOAT;
+            memcpy(&buf[pos], &floatVal, sizeof(floatVal));
+            pos += sizeof(floatVal);
+        } else {
+            jniThrowException(env,
+                    "java/lang/IllegalArgumentException",
+                    "Invalid payload item type");
+            return -1;
+        }
+        env->DeleteLocalRef(item);
+    }
+
+    buf[0] = EVENT_TYPE_LIST;
+    buf[1] = copied;
+    buf[pos++] = '\n';
+    return __android_log_security_bwrite(tag, buf, pos);
+}
+
+static void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) {
+    struct logger_list *logger_list;
+    if (startTime) {
+        logger_list = android_logger_list_alloc_time(loggerMode,
+                log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0);
+    } else {
+        logger_list = android_logger_list_alloc(loggerMode, 0, 0);
+    }
+    if (!logger_list) {
+        jniThrowIOException(env, errno);
+        return;
+    }
+
+    if (!android_logger_open(logger_list, LOG_ID_SECURITY)) {
+        jniThrowIOException(env, errno);
+        android_logger_list_free(logger_list);
+        return;
+    }
+
+    while (1) {
+        log_msg log_msg;
+        int ret = android_logger_list_read(logger_list, &log_msg);
+
+        if (ret == 0) {
+            break;
+        }
+        if (ret < 0) {
+            if (ret == -EINTR) {
+                continue;
+            }
+            if (ret == -EINVAL) {
+                jniThrowException(env, "java/io/IOException", "Event too short");
+            } else if (ret != -EAGAIN) {
+                jniThrowIOException(env, -ret);  // Will throw on return
+            }
+            break;
+        }
+
+        if (log_msg.id() != LOG_ID_SECURITY) {
+            continue;
+        }
+
+        jsize len = ret;
+        jbyteArray array = env->NewByteArray(len);
+        if (array == NULL) {
+            break;
+        }
+
+        jbyte *bytes = env->GetByteArrayElements(array, NULL);
+        memcpy(bytes, log_msg.buf, len);
+        env->ReleaseByteArrayElements(array, bytes, 0);
+
+        jobject event = env->NewObject(gEventClass, gEventInitID, array);
+        if (event == NULL) {
+            break;
+        }
+
+        env->CallBooleanMethod(out, gCollectionAddID, event);
+        env->DeleteLocalRef(event);
+        env->DeleteLocalRef(array);
+    }
+
+    android_logger_list_close(logger_list);
+}
+
+static void android_auditing_SecurityLog_readEvents(JNIEnv* env, jobject /* clazz */,
+                                             jobject out) {
+
+    if (out == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out);
+}
+
+static void android_auditing_SecurityLog_readEventsSince(JNIEnv* env, jobject /* clazz */,
+                                             jlong timestamp,
+                                             jobject out) {
+
+    if (out == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out);
+}
+
+static void android_auditing_SecurityLog_readPreviousEvents(JNIEnv* env, jobject /* clazz */,
+                                             jobject out) {
+
+    if (out == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
+}
+
+static void android_auditing_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobject /* clazz */,
+                                             jlong timestamp,
+                                             jobject out) {
+    if (out == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, out);
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gRegisterMethods[] = {
+    /* name, signature, funcPtr */
+    { "isLoggingEnabled",
+      "()Z",
+      (void*) android_auditing_SecurityLog_isLoggingEnabled
+    },
+    { "writeEvent",
+      "(ILjava/lang/String;)I",
+      (void*) android_auditing_SecurityLog_writeEvent_String
+    },
+    { "writeEvent",
+      "(I[Ljava/lang/Object;)I",
+      (void*) android_auditing_SecurityLog_writeEvent_Array
+    },
+    { "readEvents",
+      "(Ljava/util/Collection;)V",
+      (void*) android_auditing_SecurityLog_readEvents
+    },
+    { "readEventsSince",
+      "(JLjava/util/Collection;)V",
+      (void*) android_auditing_SecurityLog_readEventsSince
+    },
+    { "readPreviousEvents",
+      "(Ljava/util/Collection;)V",
+      (void*) android_auditing_SecurityLog_readPreviousEvents
+    },
+    { "readEventsOnWrapping",
+      "(JLjava/util/Collection;)V",
+      (void*) android_auditing_SecurityLog_readEventsOnWrapping
+    },
+};
+
+static struct { const char *name; jclass *clazz; } gClasses[] = {
+    { "android/auditing/SecurityLog$SecurityEvent", &gEventClass },
+    { "java/lang/Integer", &gIntegerClass },
+    { "java/lang/Long", &gLongClass },
+    { "java/lang/Float", &gFloatClass },
+    { "java/lang/String", &gStringClass },
+    { "java/util/Collection", &gCollectionClass },
+};
+
+static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
+    { &gIntegerClass, "value", "I", &gIntegerValueID },
+    { &gLongClass, "value", "J", &gLongValueID },
+    { &gFloatClass, "value", "F", &gFloatValueID },
+};
+
+static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
+    { &gEventClass, "<init>", "([B)V", &gEventInitID },
+    { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
+};
+
+int register_android_auditing_SecurityLog(JNIEnv* env) {
+    for (int i = 0; i < NELEM(gClasses); ++i) {
+        jclass clazz = FindClassOrDie(env, gClasses[i].name);
+        *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz);
+    }
+
+    for (int i = 0; i < NELEM(gFields); ++i) {
+        *gFields[i].id = GetFieldIDOrDie(env,
+                *gFields[i].c, gFields[i].name, gFields[i].ft);
+    }
+
+    for (int i = 0; i < NELEM(gMethods); ++i) {
+        *gMethods[i].id = GetMethodIDOrDie(env,
+                *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
+    }
+
+    return RegisterMethodsOrDie(
+            env,
+            "android/auditing/SecurityLog",
+            gRegisterMethods, NELEM(gRegisterMethods));
+}
+
+}; // namespace android
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index e4e73a4..34877e0 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -37,8 +37,12 @@
     return reinterpret_cast<Canvas*>(canvasHandle);
 }
 
-static void finalizer(JNIEnv* env, jobject clazz, jlong canvasHandle) {
-    delete get_canvas(canvasHandle);
+static void delete_canvas(Canvas* canvas) {
+    delete canvas;
+}
+
+static jlong getNativeFinalizer(JNIEnv* env, jobject clazz) {
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&delete_canvas));
 }
 
 // Native wrapper constructor used by Canvas(Bitmap)
@@ -710,7 +714,7 @@
 }; // namespace CanvasJNI
 
 static const JNINativeMethod gMethods[] = {
-    {"finalizer", "(J)V", (void*) CanvasJNI::finalizer},
+    {"getNativeFinalizer", "()J", (void*) CanvasJNI::getNativeFinalizer},
     {"initRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster},
     {"native_setBitmap", "!(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap},
     {"native_isOpaque","!(J)Z", (void*) CanvasJNI::isOpaque},
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 42f3fb0..61f185e 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -656,18 +656,59 @@
 }
 
 // ----------------------------------------------------------------------------
-static jint android_media_AudioTrack_get_native_frame_count(JNIEnv *env,  jobject thiz) {
+static jint android_media_AudioTrack_get_buffer_size_frames(JNIEnv *env,  jobject thiz) {
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
     if (lpTrack == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException",
-            "Unable to retrieve AudioTrack pointer for frameCount()");
+            "Unable to retrieve AudioTrack pointer for getBufferSizeInFrames()");
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+
+    ssize_t result = lpTrack->getBufferSizeInFrames();
+    if (result < 0) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Internal error detected in getBufferSizeInFrames() = " + result);
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    return (jint)result;
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_set_buffer_size_frames(JNIEnv *env,
+        jobject thiz, jint bufferSizeInFrames) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+    if (lpTrack == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioTrack pointer for setBufferSizeInFrames()");
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    // Value will be coerced into the valid range.
+    // But internal values are unsigned, size_t, so we need to clip
+    // against zero here where it is signed.
+    if (bufferSizeInFrames < 0) {
+        bufferSizeInFrames = 0;
+    }
+    ssize_t result = lpTrack->setBufferSizeInFrames(bufferSizeInFrames);
+    if (result < 0) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Internal error detected in setBufferSizeInFrames() = " + result);
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    return (jint)result;
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_buffer_capacity_frames(JNIEnv *env,  jobject thiz) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+    if (lpTrack == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioTrack pointer for getBufferCapacityInFrames()");
         return (jint)AUDIO_JAVA_ERROR;
     }
 
     return lpTrack->frameCount();
 }
 
-
 // ----------------------------------------------------------------------------
 static jint android_media_AudioTrack_set_playback_rate(JNIEnv *env,  jobject thiz,
         jint sampleRateInHz) {
@@ -857,6 +898,17 @@
     return (jint)lpTrack->latency();
 }
 
+// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_underrun_count(JNIEnv *env,  jobject thiz) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+
+    if (lpTrack == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioTrack pointer for getUnderrunCount()");
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    return (jint)lpTrack->getUnderrunCount();
+}
 
 // ----------------------------------------------------------------------------
 static jint android_media_AudioTrack_get_timestamp(JNIEnv *env,  jobject thiz, jlongArray jTimestamp) {
@@ -1073,8 +1125,12 @@
     {"native_write_short",   "([SIIIZ)I",(void *)android_media_AudioTrack_writeArray<jshortArray>},
     {"native_write_float",   "([FIIIZ)I",(void *)android_media_AudioTrack_writeArray<jfloatArray>},
     {"native_setVolume",     "(FF)V",    (void *)android_media_AudioTrack_set_volume},
-    {"native_get_native_frame_count",
-                             "()I",      (void *)android_media_AudioTrack_get_native_frame_count},
+    {"native_get_buffer_size_frames",
+                             "()I",      (void *)android_media_AudioTrack_get_buffer_size_frames},
+    {"native_set_buffer_size_frames",
+                             "(I)I",     (void *)android_media_AudioTrack_set_buffer_size_frames},
+    {"native_get_buffer_capacity_frames",
+                             "()I",      (void *)android_media_AudioTrack_get_buffer_capacity_frames},
     {"native_set_playback_rate",
                              "(I)I",     (void *)android_media_AudioTrack_set_playback_rate},
     {"native_get_playback_rate",
@@ -1094,6 +1150,7 @@
     {"native_set_position",  "(I)I",     (void *)android_media_AudioTrack_set_position},
     {"native_get_position",  "()I",      (void *)android_media_AudioTrack_get_position},
     {"native_get_latency",   "()I",      (void *)android_media_AudioTrack_get_latency},
+    {"native_get_underrun_count", "()I",      (void *)android_media_AudioTrack_get_underrun_count},
     {"native_get_timestamp", "([J)I",    (void *)android_media_AudioTrack_get_timestamp},
     {"native_set_loop",      "(III)I",   (void *)android_media_AudioTrack_set_loop},
     {"native_reload_static", "()I",      (void *)android_media_AudioTrack_reload},
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index d2c99fd..a6c61de 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -72,10 +72,16 @@
 // ----------------------------------------------------------------------------
 
 static jint android_view_DisplayListCanvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) {
+    if (!Caches::hasInstance()) {
+        android::uirenderer::renderthread::RenderProxy::staticFence();
+    }
     return Caches::getInstance().maxTextureSize;
 }
 
 static jint android_view_DisplayListCanvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) {
+    if (!Caches::hasInstance()) {
+        android::uirenderer::renderthread::RenderProxy::staticFence();
+    }
     return Caches::getInstance().maxTextureSize;
 }
 
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 75077df..a65cdb8 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" />
@@ -94,6 +96,10 @@
     <protected-broadcast android:name="android.app.action.EXIT_DESK_MODE" />
     <protected-broadcast android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED" />
 
+    <protected-broadcast android:name="android.app.action.BUGREPORT_SHARING_DECLINED" />
+    <protected-broadcast android:name="android.app.action.BUGREPORT_FAILED" />
+    <protected-broadcast android:name="android.app.action.BUGREPORT_SHARE" />
+
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_UPDATE_OPTIONS" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_DELETED" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_DISABLED" />
@@ -220,6 +226,8 @@
     <protected-broadcast android:name="android.intent.action.MEDIA_UNMOUNTABLE" />
     <protected-broadcast android:name="android.intent.action.MEDIA_EJECT" />
 
+    <protected-broadcast android:name="android.intent.action.PICTURE_IN_PICTURE_BUTTON" />
+
     <protected-broadcast android:name="android.net.conn.CAPTIVE_PORTAL" />
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE" />
     <!-- @deprecated.  Only {@link android.net.ConnectivityManager.CONNECTIVITY_ACTION} is sent. -->
@@ -249,6 +257,8 @@
     <protected-broadcast android:name="com.android.server.WifiManager.action.START_SCAN" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.START_PNO" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
+    <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
+    <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" />
@@ -385,6 +395,7 @@
     <protected-broadcast android:name="com.android.server.device_idle.STEP_LIGHT_IDLE_STATE" />
     <protected-broadcast android:name="com.android.server.Wifi.action.TOGGLE_PNO" />
     <protected-broadcast android:name="intent.action.ACTION_RF_BAND_INFO" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_RESOURCE_GRANTED" />
 
     <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED" />
     <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL" />
@@ -2828,6 +2839,12 @@
     <permission android:name="android.permission.ACCESS_EPHEMERAL_APPS"
             android:protectionLevel="signature" />
 
+    <!-- Allows receiving the usage of media resource e.g. video/audio codec and
+         graphic memory.
+         @hide -->
+    <permission android:name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"
+                android:protectionLevel="signature|privileged" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
@@ -2977,6 +2994,18 @@
             </intent-filter>
         </activity>
 
+        <!-- Activity to prompt user if it's ok to create a new user sandbox for a
+             specified account. -->
+        <activity android:name="com.android.internal.app.ConfirmUserCreationActivity"
+                android:excludeFromRecents="true"
+                android:process=":ui"
+                android:theme="@style/Theme.Material.DayNight.Dialog.Alert">
+            <intent-filter android:priority="1000">
+                <action android:name="android.os.action.CREATE_USER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <receiver android:name="com.android.server.BootReceiver"
                 android:systemUserOnly="true">
             <intent-filter android:priority="1000">
diff --git a/core/res/res/drawable/ic_notification_alert.xml b/core/res/res/drawable/ic_notification_alert.xml
new file mode 100644
index 0000000..d17dfc1
--- /dev/null
+++ b/core/res/res/drawable/ic_notification_alert.xml
@@ -0,0 +1,33 @@
+<!--
+Copyright (C) 2016 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M18.4,2.2L17.0,3.6c2.0,1.4 3.3,3.7 3.5,6.4l2.0,0.0C22.3,6.8 20.8,4.0 18.4,2.2z"
+        android:fillColor="#231F20"/>
+    <path
+        android:pathData="M7.1,3.6L5.7,2.2C3.3,4.0 1.7,6.8 1.5,10.0l2.0,0.0C3.7,7.3 5.0,5.0 7.1,3.6z"
+        android:fillColor="#231F20"/>
+    <path
+        android:pathData="M18.5,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.5,3.5C13.5,2.7 12.8,2.0 12.0,2.0s-1.5,0.7 -1.5,1.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.5,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0l-2.0,-2.0L18.5,10.5zM13.0,16.5l-2.0,0.0l0.0,-2.0l2.0,0.0L13.0,16.5zM13.0,12.5l-2.0,0.0l0.0,-6.0l2.0,0.0L13.0,12.5z"
+        android:fillColor="#231F20"/>
+    <path
+        android:pathData="M12.0,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0L10.0,20.0C10.0,21.1 10.9,22.0 12.0,22.0z"
+        android:fillColor="#231F20"/>
+</vector>
diff --git a/core/res/res/drawable/ic_notification_block.xml b/core/res/res/drawable/ic_notification_block.xml
new file mode 100644
index 0000000..27690740
--- /dev/null
+++ b/core/res/res/drawable/ic_notification_block.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2016 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.0,2.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0zM4.0,12.0c0.0,-4.42 3.58,-8.0 8.0,-8.0 1.85,0.0 3.5,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4.0,13.85 4.0,12.0zm8.0,8.0c-1.85,0.0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20.0,10.15 20.0,12.0c0.0,4.42 -3.58,8.0 -8.0,8.0z"/>
+</vector>
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 36c167e..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sluit persoonlike data soos kredietkaartnommers en wagwoorde in."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Beheer vertoonskermvergroting"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Beheer die vertoonskerm se zoemvlak en posisionering."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Voer gebare uit"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan tik, swiep, knyp en ander gebare uitvoer."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"deaktiveer of verander statusbalk"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Laat die program toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"wees die statusbalk"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diverse"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Jy stel die belangrikheid van hierdie kennisgewings."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrik as gevolg van die mense wat betrokke is."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeer om \'n nuwe gebruiker by te voeg, maar word tans verbied."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeer tans om \'n nuwe gebruiker by te voeg, maar die gebruikerlimiet is bereik."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeer tans om \'n nuwe gebruiker by te voeg, maar die rekening "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" bestaan reeds op hierdie toestel. Gaan in elk geval voort?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeer tans om \'n nuwe gebruiker vir die rekening "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" by te voeg. Gaan voort?"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ec16add..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"እንደ የክሬዲት ካርድ ቁጥሮች እና የይለፍ ቃላት ያሉ የግል ውሂብ ያካትታል።"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"የመቆጣጠሪያ ማሳያ እንዲጎላ አደራረግ"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"የማሳያውን የማጉያ ደረጃ እና አቀማመጥ ይቆጣጠሩ።"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"የጣት ምልክቶችን ያከናውኑ"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"መታ ማድረግ፣ ማንሸራተት፣ መቆንጠጥ እና ሌሎች የጣት ምልክቶችን ማከናወን ይችላል።"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"የሁኔቴ አሞሌ አቦዝን ወይም ቀይር"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"የስርዓት አዶዎችን ወደ ሁኔታ አሞሌ ላለማስቻል ወይም ለማከል እና ለማስወገድ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"የሁኔታ አሞሌ መሆን"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 12ef759..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>
@@ -260,6 +269,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"يتضمن بيانات شخصية مثل أرقام بطاقات الائتمان وكلمات المرور."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"التحكم في تكبير الشاشة"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"يمكنك التحكم في مستوى التكبير/التصغير للشاشة وتحديد الموضع."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"تنفيذ إيماءات"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"يمكن النقر والتمرير بسرعة والتصغير وتنفيذ إيماءات أخرى."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"تعطيل شريط الحالة أو تعديله"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"للسماح للتطبيق بتعطيل شريط الحالة أو إضافة رموز نظام وإزالتها."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"العمل كشريط للحالة"</string>
@@ -1058,6 +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>
+    <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>
@@ -1582,4 +1599,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>
+    <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-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 7f0e6d7..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Kredit kartı nömrələri və parollar kimi şəxsi məlumatlar daxildir."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ekran böyütməsinə nəzarət edin"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ekran yaxınlaşdırma səviyyəsi və yerləşdirməsinə nəzarət edin."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Jestlər ilə əməliyyat aparın"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Digər jestlərə tıklaya, sürüşdürə və əməliyyat apara bilərsiniz."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"status panelini deaktivləşdir və ya dəyişdir"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Tətbiqə status panelini deaktiv etməyə və ya sistem ikonalarını əlavə etmək və ya silmək imkanı verir."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"status paneli edin"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Müxtəlif"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Bildirişlərin əhəmiyyətini Siz ayarlaryırsınız."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"İnsanlar cəlb olunduğu üçün bu vacibdir."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yeni istifadəçi əlavə etməyə çalışır, lakin hal-hazırda qadağandır."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yeni istifadəçi əlavə etməyə çalışır, lakin istifadəçi limitinə çatılıb."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yeni istifadəçi əlavə etməyə çalışır, lakin "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hesabı bu cihazda artıq mövcuddur. Hər bir halda davam edilsin?"</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ı üçün yeni istifadəçi əlavə etməyə çalışır. Davam edilsin?"</string>
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ac5ce66..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>
@@ -257,6 +266,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Upravljaj uvećanjem prikaza"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Upravlja nivoom zumiranja prikaza i određivanjem položaja."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Obavljanje pokreta"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"onemogućavanje ili izmena statusne trake"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Dozvoljava aplikaciji da onemogući statusnu traku ili da dodaje i uklanja sistemske ikone."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"funkcionisanje kao statusna traka"</string>
@@ -1037,6 +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>
+    <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>
@@ -1528,4 +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>
+    <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 301e1e3..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Включва лични данни, като например номера на кредитни карти и пароли."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Управление на увеличението на дисплея"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Управление на нивото на мащаба и позиционирането на дисплея."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Извършване на жестове"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Можете да докосвате, да прекарвате пръст, да събирате пръсти и да извършвате други жестове."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"деактивиране или промяна на лентата на състоянието"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Разрешава на приложението да деактивира лентата на състоянието или да добавя и премахва системни икони."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"изпълняване на ролята на лента на състоянието"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 9c88d44..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ক্রেডিট কার্ডের নম্বর ও পাসওয়ার্ডগুলির মতো ব্যক্তিগত তথ্য অন্তর্ভুক্ত করে৷"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"প্রদর্শনের বৃহত্তরীকরণ ব্যবস্থা নিয়ন্ত্রণ করুন"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"প্রদর্শনের জুমের স্তর এবং অবস্থান নির্ধারন নিয়ন্ত্রণ করুন৷"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"অঙ্গভঙ্গির কাজগুলি সম্পাদন করুন"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"আলতো চাপ দেওয়া, সোয়াইপ, পিঞ্চ করা এবং অন্যান্য অঙ্গভঙ্গির কাজগুলি সম্পাদন করতে পারবেন৷"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"স্থিতি দন্ড নিষ্ক্রিয় অথবা সংশোধন করে"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"অ্যাপ্লিকেশানকে স্থিতি দন্ড অক্ষম করতে এবং সিস্টেম আইকনগুলি সরাতে দেয়৷"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"স্থিতি দন্ডে থাকুন"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 8554b843..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclou dades personals com ara números de targetes de crèdit i contrasenyes."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controla l\'ampliació de la pantalla"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controla el nivell i el posicionament del zoom de la pantalla."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Utilitza gestos"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Pot tocar, lliscar, pessigar i utilitzar altres gestos."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"desactivar o modificar la barra d\'estat"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permet que l\'aplicació desactivi la barra d\'estat o afegeixi i elimini icones del sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"aparèixer a la barra d\'estat"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 2eca49a..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sledování zahrnuje osobní údaje, jako jsou například čísla kreditních karet a hesla."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Nastavení zvětšení obsahu obrazovky"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Určuje umístění a úroveň přiblížení displeje."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Provádění gest"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Může provádět gesta klepnutí, přejetí, stažení prstů a další."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"zakázání či změny stavového řádku"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje aplikaci zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"vydávání se za stavový řádek"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +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>
+    <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 2a719b0..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Dette omfatter personlige data såsom kreditkortnumre og adgangskoder."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrollér skærmforstørrelsen"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrollér skærmens zoomniveau og position."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Udfør bevægelser"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trykke, stryge, knibe sammen og udføre andre bevægelser."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"deaktiver eller rediger statuslinje"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Tillader, at appen kan deaktivere statusbjælken eller tilføje og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"vær statusbjælken"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 d116a24..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>
@@ -53,17 +53,17 @@
     <string name="serviceErased" msgid="1288584695297200972">"Löschvorgang erfolgreich."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"Falsches Passwort."</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI abgeschlossen."</string>
-    <string name="badPin" msgid="9015277645546710014">"Die von Ihnen eingegebene alte PIN ist nicht korrekt."</string>
-    <string name="badPuk" msgid="5487257647081132201">"Der von Ihnen eingegebene PUK ist nicht korrekt."</string>
-    <string name="mismatchPin" msgid="609379054496863419">"Die von Ihnen eingegebenen PIN-Nummern stimmen nicht überein."</string>
-    <string name="invalidPin" msgid="3850018445187475377">"Geben Sie eine PIN ein, die 4 bis 8 Zahlen enthält."</string>
-    <string name="invalidPuk" msgid="8761456210898036513">"Geben Sie eine mindestens achtstellige PUK ein."</string>
-    <string name="needPuk" msgid="919668385956251611">"Ihre SIM-Karte ist mit einem PUK gesperrt. Geben Sie zum Entsperren den PUK-Code ein."</string>
-    <string name="needPuk2" msgid="4526033371987193070">"Geben Sie zum Entsperren der SIM-Karte den PUK2 ein."</string>
+    <string name="badPin" msgid="9015277645546710014">"Die von dir eingegebene alte PIN ist nicht korrekt."</string>
+    <string name="badPuk" msgid="5487257647081132201">"Der von dir eingegebene PUK ist nicht korrekt."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"Die von dir eingegebenen PIN-Nummern stimmen nicht überein."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"Gib eine PIN ein, die 4 bis 8 Zahlen enthält."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"Gib eine mindestens achtstellige PUK ein."</string>
+    <string name="needPuk" msgid="919668385956251611">"Deine SIM-Karte ist mit einem PUK gesperrt. Gib zum Entsperren den PUK-Code ein."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Gib zum Entsperren der SIM-Karte den PUK2 ein."</string>
     <string name="enablePin" msgid="209412020907207950">"Fehler. SIM-/RUIM-Sperre aktivieren."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
-      <item quantity="other">Sie haben noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche, bevor Ihre SIM-Karte gesperrt wird.</item>
-      <item quantity="one">Sie haben noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor Ihre SIM-Karte gesperrt wird.</item>
+      <item quantity="other">Du hast noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche, bevor deine SIM-Karte gesperrt wird.</item>
+      <item quantity="one">Du hast noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor deine SIM-Karte gesperrt wird.</item>
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -87,7 +87,7 @@
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Anrufer-ID ist standardmäßig nicht beschränkt. Nächster Anruf: Beschränkt"</string>
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Anrufer-ID ist standardmäßig nicht beschränkt. Nächster Anruf: Nicht beschränkt"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Dienst nicht eingerichtet."</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"Sie können die Einstellung für die Anrufer-ID nicht ändern."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Du kannst die Einstellung für die Anrufer-ID nicht ändern."</string>
     <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Eingeschränkter Zugriff geändert"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"Daten-Dienst ist gesperrt."</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Notruf ist gesperrt."</string>
@@ -148,7 +148,7 @@
     <string name="httpErrorAuth" msgid="1435065629438044534">"Bei der Authentifizierung ist ein Fehler aufgetreten."</string>
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Authentifizierung via Proxyserver ist fehlgeschlagen."</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"Verbindung zum Server konnte nicht hergestellt werden."</string>
-    <string name="httpErrorIO" msgid="2340558197489302188">"Kommunikation mit dem Server konnte nicht hergestellt werden. Bitte versuchen Sie es später erneut."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Kommunikation mit dem Server konnte nicht hergestellt werden. Bitte versuche es später erneut."</string>
     <string name="httpErrorTimeout" msgid="4743403703762883954">"Zeitüberschreitung bei Serververbindung."</string>
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Die Seite enthält zu viele Server-Redirects."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Das Protokoll wird nicht unterstützt."</string>
@@ -156,25 +156,25 @@
     <string name="httpErrorBadUrl" msgid="3636929722728881972">"Die Seite kann nicht geöffnet werden, weil die URL ungültig ist."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"Auf die Datei konnte nicht zugegriffen werden."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Die angeforderte Datei wurde nicht gefunden."</string>
-    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Es werden zurzeit zu viele Anfragen verarbeitet. Versuchen Sie es später erneut."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Es werden zurzeit zu viele Anfragen verarbeitet. Versuche es später erneut."</string>
     <string name="notification_title" msgid="8967710025036163822">"Fehler bei Anmeldung für <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"Synchronisierung"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronisierung"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Zu viele <xliff:g id="CONTENT_TYPE">%s</xliff:g> gelöscht."</string>
-    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Der Tablet-Speicher ist voll. Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
-    <string name="low_memory" product="watch" msgid="4415914910770005166">"Der Speicher Ihrer Uhr ist voll. Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
-    <string name="low_memory" product="tv" msgid="516619861191025923">"Der TV-Speicher ist voll. Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
-    <string name="low_memory" product="default" msgid="3475999286680000541">"Der Handyspeicher ist voll! Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Der Tablet-Speicher ist voll. Lösche Dateien, um Speicherplatz freizugeben."</string>
+    <string name="low_memory" product="watch" msgid="4415914910770005166">"Der Speicher deiner Uhr ist voll. Lösche Dateien, um Speicherplatz freizugeben."</string>
+    <string name="low_memory" product="tv" msgid="516619861191025923">"Der TV-Speicher ist voll. Lösche Dateien, um Speicherplatz freizugeben."</string>
+    <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 Ihr Arbeitsprofil und alle zugehörigen Daten gelöscht. Wenden Sie sich für weitere Hilfe an Ihren 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="factory_reset_message" msgid="4905025204141900666">"Die Admin-App kann nicht verwendet werden, da sie beschädigt wurde oder Komponenten fehlen. Die Daten auf Ihrem Gerät werden nun gelöscht. Wenden Sie sich für weitere Hilfe an Ihren Administrator."</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">"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>
     <string name="power_dialog" product="tv" msgid="6153888706430556356">"TV-Optionen"</string>
@@ -194,13 +194,13 @@
     <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öchten Sie das Gerät herunterfahren?"</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>
-    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Möchten Sie im abgesicherten Modus neu starten? Dadurch werden alle Apps von Drittanbietern deaktiviert, die Sie installiert haben. Sie werden jedoch nach einem weiteren Neustart wiederhergestellt."</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Möchtest du im abgesicherten Modus neu starten? Dadurch werden alle Apps von Drittanbietern deaktiviert, die du installiert hast. Die Apps werden jedoch nach einem weiteren Neustart wiederhergestellt."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Kürzlich geöffnet"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"Keine kürzlich geöffneten Apps"</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet-Optionen"</string>
@@ -210,7 +210,16 @@
     <string name="global_action_power_off" msgid="4471879440839879722">"Ausschalten"</string>
     <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 Ihres Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte haben Sie etwas Geduld."</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,9 +254,9 @@
     <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 Sie interagieren, werden abgerufen."</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>
     <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Berührte Elemente werden laut vorgelesen und der Bildschirm kann über Gesten erkundet werden."</string>
     <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Verbesserte Web-Bedienung aktivieren"</string>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Einschließlich personenbezogener Daten wie Kreditkartennummern und Passwörter."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Displayvergrößerung festlegen"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Legt die Zoom-Stufe des Displays und die Zoom-Position auf dem Display fest."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Bewegungen möglich"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Tippen, Wischen, Zusammenziehen und andere Bewegungen möglich."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"Statusleiste deaktivieren oder ändern"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"Statusleiste darstellen"</string>
@@ -269,23 +280,23 @@
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"Ausgehende Anrufe umleiten"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Ermöglicht der App die Erkennung der während eines ausgehenden Anrufs gewählten Nummer und gibt ihr die Möglichkeit, den Anruf an eine andere Nummer umzuleiten oder den Anruf ganz abzubrechen"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"SMS empfangen"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an dein Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie dir anzuzeigen."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"MMS empfangen"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an dein Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie dir anzuzeigen."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Cell Broadcast-Nachrichten lesen"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ermöglicht der App, von Ihrem Gerät empfangene Cell Broadcast-Nachrichten zu lesen. Cell Broadcast-Benachrichtigungen werden an einigen Standorten gesendet, um Sie über Notfallsituationen zu informieren. Schädliche Apps können die Leistung oder den Betrieb Ihres Geräts beeinträchtigen, wenn eine Cell Broadcast-Notfallbenachrichtigung eingeht."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ermöglicht der App, von deinem Gerät empfangene Cell Broadcast-Nachrichten zu lesen. Cell Broadcast-Benachrichtigungen werden an einigen Standorten gesendet, um dich über Notfallsituationen zu informieren. Schädliche Apps können die Leistung oder den Betrieb deines Geräts beeinträchtigen, wenn eine Cell Broadcast-Notfallbenachrichtigung eingeht."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Abonnierte Feeds lesen"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ermöglicht der App, Details zu den zurzeit synchronisierten Feeds abzurufen"</string>
     <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 Ihre Bestätigung senden."</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 Sie gesendet wurden, überwacht und gelöscht werden, bevor sie Ihnen angezeigt werden."</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>
@@ -313,49 +324,49 @@
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Ermöglicht der App, dauerhafte Broadcasts zu senden, die auch nach Ende des Broadcasts bestehen bleiben. Ein zu intensiver Einsatz kann das Gerät langsam oder instabil machen, weil zu viel Arbeitsspeicher belegt wird."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Ermöglicht der App, dauerhafte Broadcasts zu senden, die auch nach Ende des Broadcasts bestehen bleiben. Ein zu intensiver Einsatz kann das Telefon langsam oder instabil machen, weil zu viel Arbeitsspeicher belegt wird."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"Kontakte lesen"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Ermöglicht der App, Daten zu den auf Ihrem Tablet gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der Sie bestimmte Personen angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert haben. Die Berechtigung erlaubt Apps, Ihre Kontaktdaten zu speichern, und schädliche Apps können Kontaktdaten ohne Ihr Wissen weiterleiten."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Ermöglicht der App, Daten zu den auf Ihrem Fernseher gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der Sie bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert haben. Diese Berechtigung ermöglicht der App, Ihre Kontaktdaten zu speichern. Schädliche Apps können so Kontaktdaten ohne Ihr Wissen weitergeben."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Ermöglicht der App, Daten zu den auf Ihrem Telefon gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der Sie bestimmte Personen angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert haben. Die Berechtigung erlaubt Apps, Ihre Kontaktdaten zu speichern, und schädliche Apps können Kontaktdaten ohne Ihr Wissen weiterleiten."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Ermöglicht der App, Daten zu den auf deinem Tablet gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der du bestimmte Personen angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern, und schädliche Apps können Kontaktdaten ohne dein Wissen weiterleiten."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Ermöglicht der App, Daten zu den auf deinem Fernseher gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der du bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Diese Berechtigung ermöglicht der App, deine Kontaktdaten zu speichern. Schädliche Apps können so Kontaktdaten ohne dein Wissen weitergeben."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Ermöglicht der App, Daten zu den auf deinem Telefon gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der du bestimmte Personen angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern, und schädliche Apps können Kontaktdaten ohne dein Wissen weiterleiten."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"Kontakte ändern"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Ermöglicht der App, Daten zu Kontakten, die auf Ihrem Tablet gespeichert sind, zu ändern, einschließlich der Häufigkeit, mit der Sie bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert haben. Die Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Ermöglicht der App, Daten zu den auf Ihrem Fernseher gespeicherten Kontakten zu ändern, einschließlich der Häufigkeit, mit der Sie bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert haben. 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 Ihrem Telefon gespeichert sind, zu ändern, einschließlich der Häufigkeit, mit der Sie bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert haben. Die Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Ermöglicht der App, Daten zu Kontakten, die auf deinem Tablet 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="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 Sie auf Ihrem Tablet ändern können, hinzuzufügen, zu entfernen und zu ändern, einschließlich der 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 Sie auf Ihrem Fernseher bearbeiten können ‒ 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>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Ermöglicht der App, Termine, die Sie auf Ihrem Telefon ändern können, hinzuzufügen, zu entfernen und zu ändern, einschließlich der 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="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>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Ermöglicht der App, Termine, die du auf deinem Telefon ä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 kann Termine ohne Wissen des Inhabers ändern."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Auf zusätzliche Dienstanbieterbefehle für Standort zugreifen"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ermöglicht der App, auf zusätzliche Standortanbieterbefehle zuzugreifen. Damit könnte die App die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"Auf genauen Standort zugreifen (GPS- und netzwerkbasiert)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Ermöglicht der App, Ihre genaue Position anhand von GPS-Daten (Global Positioning System) oder über Netzwerkstandortquellen wie Sendemasten oder WLAN zu ermitteln. Diese Standortdienste müssen auf Ihrem Gerät verfügbar und aktiviert sein, damit die App sie verwenden kann. Apps können Ihren Standort anhand dieser Daten ermitteln und verbrauchen eventuell zusätzliche Akkuleistung."</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Ermöglicht der App, deine genaue Position anhand von GPS-Daten (Global Positioning System) oder über Netzwerkstandortquellen wie Sendemasten oder WLAN zu ermitteln. Diese Standortdienste müssen auf deinem Gerät verfügbar und aktiviert sein, damit die App sie verwenden kann. Apps können deinen Standort anhand dieser Daten ermitteln und verbrauchen eventuell zusätzliche Akkuleistung."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"Auf den ungefähren Standort zugreifen (netzwerkbasiert)"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Ermöglicht der App, Ihren ungefähren Standort zu ermitteln. Diese Standortangabe stammt von Standortdiensten, die Netzwerkstandortquellen wie etwa Sendemasten oder WLAN verwenden. Diese Standortdienste müssen auf Ihrem Gerät verfügbar und aktiviert sein, damit die App sie verwenden kann. Apps können Ihren ungefähren Standort anhand dieser Daten ermitteln."</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Ermöglicht der App, deinen ungefähren Standort zu ermitteln. Diese Standortangabe stammt von Standortdiensten, die Netzwerkstandortquellen wie etwa Sendemasten oder WLAN verwenden. Diese Standortdienste müssen auf deinem Gerät verfügbar und aktiviert sein, damit die App sie verwenden kann. Apps können deinen ungefähren Standort anhand dieser Daten ermitteln."</string>
     <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>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"Ermöglicht der App, ohne Ihr Eingreifen Telefonnummern zu wählen. Dies kann zu unerwarteten Kosten und Anrufen führen. Beachten Sie, dass die App keine Notrufnummern wählen kann. Schädliche Apps verursachen möglicherweise Kosten, indem sie Anrufe ohne Ihre Bestätigung tätigen."</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Ermöglicht der App, ohne dein Eingreifen Telefonnummern zu wählen. Dies kann zu unerwarteten Kosten und Anrufen führen. Beachte, dass die App keine Notrufnummern wählen kann. Schädliche Apps verursachen möglicherweise Kosten, indem sie Anrufe ohne deine Bestätigung tätigen."</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"Zugriff auf IMS-Anrufdienst"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Ermöglicht der App die Verwendung des IMS-Dienstes zum Tätigen von Anrufen ohne Nutzereingriffe"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"Telefonstatus und Identität abrufen"</string>
@@ -395,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>
@@ -420,19 +431,19 @@
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Erlaubt der App, Methoden zum Hinzufügen und Löschen zu verwendender Fingerabdruckvorlagen aufzurufen"</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"Fingerabdruckhardware verwenden"</string>
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Erlaubt der App, Fingerabdruckhardware zur Authentifizierung zu verwenden"</string>
-    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Fingerabdruck teilweise erkannt. Versuchen Sie es erneut."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Fingerabdruck konnte nicht verarbeitet werden. Versuchen Sie es erneut."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Fingerabdrucksensor ist verschmutzt. Reinigen Sie ihn und versuchen Sie es erneut."</string>
-    <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Finger zu schnell bewegt. Versuchen Sie es erneut."</string>
-    <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Finger zu langsam bewegt. Versuchen Sie es erneut."</string>
+    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Fingerabdruck teilweise erkannt. Versuche es erneut."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Fingerabdruck konnte nicht verarbeitet werden. Versuche es erneut."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Fingerabdrucksensor ist verschmutzt. Reinige ihn und versuche es erneut."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Finger zu schnell bewegt. Versuche es erneut."</string>
+    <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Finger zu langsam bewegt. Versuche es erneut."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Fingerabdruckhardware nicht verfügbar"</string>
-    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerabdruck kann nicht gespeichert werden. Entfernen Sie einen vorhandenen Fingerabdruck."</string>
-    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Zeitüberschreitung für Fingerabdruck. Versuchen Sie es erneut."</string>
+    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Fingerabdruck kann nicht gespeichert werden. Entferne einen vorhandenen Fingerabdruck."</string>
+    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Zeitüberschreitung für Fingerabdruck. Versuche es erneut."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerabdruckvorgang abgebrochen"</string>
-    <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche. Versuchen Sie es später erneut."</string>
-    <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bitte versuchen Sie es erneut."</string>
+    <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche. Versuche es später erneut."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bitte versuche es erneut."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -509,11 +520,11 @@
     <string name="policylab_resetPassword" msgid="4934707632423915395">"Displaysperre ändern"</string>
     <string name="policydesc_resetPassword" msgid="1278323891710619128">"Displaysperre ändern"</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"Bildschirm sperren"</string>
-    <string name="policydesc_forceLock" msgid="1141797588403827138">"Legen Sie fest, wie und wann der Bildschirm gesperrt wird."</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Lege fest, wie und wann der Bildschirm gesperrt wird."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"Alle Daten löschen"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Auf Werkseinstellungen zurücksetzen und Daten auf dem Tablet ohne Warnung löschen"</string>
     <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Auf Werkseinstellungen zurücksetzen und Daten auf dem Fernseher ohne Warnung löschen"</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Setzen Sie das Telefon auf die Werkseinstellungen zurück. Dabei werden alle Daten ohne Warnung gelöscht."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Setze das Telefon auf die Werkseinstellungen zurück. Dabei werden alle Daten ohne Warnung gelöscht."</string>
     <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Nutzerdaten löschen"</string>
     <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Daten dieses Nutzers auf diesem Tablet ohne vorherige Warnung löschen"</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Daten dieses Nutzers auf diesem Fernseher ohne vorherige Warnung löschen"</string>
@@ -650,11 +661,11 @@
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Passwort zum Entsperren eingeben"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"PIN zum Entsperren eingeben"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Falscher PIN-Code"</string>
-    <string name="keyguard_label_text" msgid="861796461028298424">"Drücken Sie zum Entsperren die Menütaste und dann auf \"0\"."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Drücke zum Entsperren die Menütaste und dann auf \"0\"."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Notrufnummer"</string>
     <string name="lockscreen_carrier_default" msgid="6169005837238288522">"Kein Dienst"</string>
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Display gesperrt"</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Drücken Sie die Menütaste, um das Telefon zu entsperren oder einen Notruf zu tätigen."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Drücke die Menütaste, um das Telefon zu entsperren oder einen Notruf zu tätigen."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Zum Entsperren die Menütaste drücken"</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Muster zum Entsperren zeichnen"</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Notfall"</string>
@@ -667,10 +678,10 @@
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Keine SIM-Karte im Tablet"</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Keine SIM-Karte im Fernseher"</string>
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Keine SIM-Karte im Telefon"</string>
-    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Legen Sie eine SIM-Karte ein."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-Karte fehlt oder ist nicht lesbar. Bitte legen Sie eine SIM-Karte ein."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Lege eine SIM-Karte ein."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-Karte fehlt oder ist nicht lesbar. Bitte lege eine SIM-Karte ein."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"SIM-Karte unbrauchbar"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Ihre SIM-Karte wurde dauerhaft deaktiviert.\n Wenden Sie sich an Ihren Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Deine SIM-Karte wurde dauerhaft deaktiviert.\n Wende dich an deinen Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Vorheriger Titel"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Nächster Titel"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Pausieren"</string>
@@ -681,31 +692,31 @@
     <string name="emergency_calls_only" msgid="6733978304386365407">"Nur Notrufe"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Netzwerk gesperrt"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"PUK-Sperre auf SIM"</string>
-    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Weitere Informationen erhalten Sie im Nutzerhandbuch oder beim Kundendienst."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Weitere Informationen erhältst du im Nutzerhandbuch oder beim Kundendienst."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"PIN eingeben"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-Karte wird entsperrt..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe Ihrer Google-Anmeldeinformationen zu entsperren.\n\n Bitte versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Wenn Sie es noch <xliff:g id="NUMBER_1">%2$d</xliff:g>-mal falsch eingeben, werden Sie aufgefordert, Ihren Fernseher mithilfe Ihrer Google-Anmeldeinformationen zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe Ihrer Google-Anmeldeinformationen zu entsperren.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g> Mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird der Fernseher auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g> Mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Der Fernseher wird nun auf die Werkseinstellungen zurückgesetzt."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt."</string>
-    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Versuchen Sie es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du hast dein Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du hast dein Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Tablet mithilfe deiner Google-Anmeldeinformationen zu entsperren.\n\n Bitte versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Wenn du es noch <xliff:g id="NUMBER_1">%2$d</xliff:g>-mal falsch eingibst, wirst du aufgefordert, deinen Fernseher mithilfe deiner Google-Anmeldeinformationen zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Telefon mithilfe deiner Google-Anmeldeinformationen zu entsperren.\n\nBitte versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g> Mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird der Fernseher auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g> Mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Der Fernseher wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Versuche es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Muster vergessen?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Kontoentsperrung"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Zu viele Schemaversuche"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Melden Sie sich zum Entsperren mit Ihrem Google-Konto an."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Melde dich zum Entsperren mit deinem Google-Konto an."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nutzername (E-Mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passwort"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Anmelden"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ungültiger  Nutzername oder ungültiges Passwort."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nutzernamen oder Passwort vergessen?\nBesuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nutzernamen oder Passwort vergessen?\nBesuche "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Überprüfung..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Entsperren"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ton ein"</string>
@@ -753,7 +764,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Navigation bestätigen"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Diese Seite verlassen"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Auf dieser Seite bleiben"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nMöchten Sie diese Seite wirklich verlassen?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nMöchtest du diese Seite wirklich verlassen?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Bestätigen"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tipp: Zum Vergrößern und Verkleinern zweimal tippen"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"AutoFill"</string>
@@ -777,20 +788,20 @@
     <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öchten Sie, dass der Browser dieses Passwort speichert?"</string>
+    <string name="save_password_message" msgid="767344687139195790">"Möchtest du, dass der Browser dieses Passwort speichert?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Nicht jetzt"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Speichern"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Nie"</string>
-    <string name="open_permission_deny" msgid="7374036708316629800">"Sie sind nicht zum Öffnen dieser Seite berechtigt."</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Du bist nicht zum Öffnen dieser Seite berechtigt."</string>
     <string name="text_copied" msgid="4985729524670131385">"Text in Zwischenablage kopiert."</string>
     <string name="more_item_label" msgid="4650918923083320495">"Mehr"</string>
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menü+"</string>
@@ -805,8 +816,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"Anfrage senden"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Sprachsuche"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\"Tippen &amp; Entdecken\" aktivieren?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\". Wenn \"Tippen &amp; Entdecken\" aktiviert ist, können Sie Beschreibungen dessen hören oder sehen, was sich unter ihren Fingern befindet, oder Gesten ausführen, um mit dem Tablet zu kommunizieren."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\". Wenn \"Tippen &amp; Entdecken\" aktiviert ist, können Sie Beschreibungen dessen hören oder sehen, was sich unter ihren Fingern befindet, oder Gesten ausführen, um mit dem Telefon zu kommunizieren."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\" an. Wenn \"Tippen &amp; Entdecken\" aktiviert ist, kannst du Beschreibungen dessen hören oder sehen, was sich unter deinen Fingern befindet, oder Gesten ausführen, um mit dem Tablet zu kommunizieren."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\" an. Wenn \"Tippen &amp; Entdecken\" aktiviert ist, kannst du Beschreibungen dessen hören oder sehen, was sich unter deinen Fingern befindet, oder Gesten ausführen, um mit dem Telefon zu kommunizieren."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Vor 1 Monat"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vor mehr als 1 Monat"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -871,7 +882,7 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der Speicherplatz wird knapp"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren möglicherweise nicht."</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Der Speicherplatz reicht nicht für das System aus. Stellen Sie sicher, dass 250 MB freier Speicherplatz vorhanden ist, und starten Sie das Gerät dann neu."</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Der Speicherplatz reicht nicht für das System aus. Stelle sicher, dass 250 MB freier Speicherplatz vorhanden sind, und starte das Gerät dann neu."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird ausgeführt"</string>
     <string name="app_running_notification_text" msgid="4653586947747330058">"Für weitere Informationen oder zum Anhalten der App tippen"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
@@ -903,21 +914,21 @@
     <string name="aerr_process" msgid="4507058997035697579">"Der Prozess \"<xliff:g id="PROCESS">%1$s</xliff:g>\" wurde beendet."</string>
     <string name="aerr_process_silence" msgid="4226685530196000222">"Silence stürzt bei <xliff:g id="PROCESS">%1$s</xliff:g> bis zum Neustart ab."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reagiert nicht.\n\nMöchten Sie die App schließen?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivität \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\" reagiert nicht.\n\nMöchten Sie sie beenden?"</string>
-    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> reagiert nicht. Möchten Sie die App schließen?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Prozess \"<xliff:g id="PROCESS">%1$s</xliff:g>\" reagiert nicht.\n\nMöchten Sie ihn beenden?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reagiert nicht.\n\nMöchtest du die App schließen?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivität \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\" reagiert nicht.\n\nMöchtest du sie beenden?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> reagiert nicht. Möchtest du die App schließen?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Prozess \"<xliff:g id="PROCESS">%1$s</xliff:g>\" reagiert nicht.\n\nMöchtest du ihn beenden?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Bericht"</string>
     <string name="wait" msgid="7147118217226317732">"Warten"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Die Seite reagiert nicht mehr.\n\nMöchten Sie die Seite schließen?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Die Seite reagiert nicht mehr.\n\nMöchtest du die Seite schließen?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"App umgeleitet"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird jetzt ausgeführt."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> wurde ursprünglich gestartet."</string>
     <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>
@@ -937,7 +948,7 @@
     <string name="dump_heap_notification" msgid="2618183274836056542">"Speicherlimit für \"<xliff:g id="PROC">%1$s</xliff:g>\" überschritten"</string>
     <string name="dump_heap_notification_detail" msgid="2075673362317481664">"Heap-Dump wurde erfasst, zum Teilen tippen"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Heap-Dump teilen?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Für den Prozess \"<xliff:g id="PROC">%1$s</xliff:g>\" wurde das Prozessspeicherlimit von <xliff:g id="SIZE">%2$s</xliff:g> überschritten. Es steht ein Heap-Dump zur Verfügung, den Sie mit dem Entwickler teilen können. Beachten Sie jedoch unbedingt, dass der Heap-Dump personenbezogene Daten von Ihnen enthalten kann, auf die die App zugreifen kann."</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"Für den Prozess \"<xliff:g id="PROC">%1$s</xliff:g>\" wurde das Prozessspeicherlimit von <xliff:g id="SIZE">%2$s</xliff:g> überschritten. Es steht ein Heap-Dump zur Verfügung, den du mit dem Entwickler teilen kannst. Beachte jedoch unbedingt, dass der Heap-Dump personenbezogene Daten von dir enthalten kann, auf die die App zugreifen kann."</string>
     <string name="sendText" msgid="5209874571959469142">"Aktion für Text auswählen"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Klingeltonlautstärke"</string>
     <string name="volume_music" msgid="5421651157138628171">"Medienlautstärke"</string>
@@ -988,30 +999,30 @@
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Einladung zum Aufbau einer Verbindung"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"Von:"</string>
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"An:"</string>
-    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Geben Sie die PIN ein:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Gib die PIN ein:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Das Tablet wird vorübergehend vom WLAN getrennt, während eine Verbindung mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> besteht."</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"Der Fernseher wird vorübergehend vom WLAN getrennt, während eine Verbindung mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> besteht."</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Das Telefon wird vorübergehend vom WLAN getrennt, während eine Verbindung mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> hergestellt wird."</string>
     <string name="select_character" msgid="3365550120617701745">"Zeichen einfügen"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS werden gesendet"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sendet eine große Anzahl SMS. Möchten Sie zulassen, dass die App weiterhin Nachrichten sendet?"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sendet eine große Anzahl SMS. Möchtest du zulassen, dass die App weiterhin Nachrichten sendet?"</string>
     <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>
-    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Sie können dies unter \"Einstellungen &gt; Apps\" ändern."</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Du kannst dies unter \"Einstellungen &gt; Apps\" ändern."</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Immer zulassen"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nie zulassen"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"SIM-Karte entfernt"</string>
-    <string name="sim_removed_message" msgid="5450336489923274918">"Das Mobilfunknetz ist erst wieder verfügbar, wenn Sie einen Neustart mit einer gültigen SIM-Karte durchführen."</string>
+    <string name="sim_removed_message" msgid="5450336489923274918">"Das Mobilfunknetz ist erst wieder verfügbar, wenn du einen Neustart mit einer gültigen SIM-Karte durchführst."</string>
     <string name="sim_done_button" msgid="827949989369963775">"Fertig"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-Karte hinzugefügt"</string>
-    <string name="sim_added_message" msgid="7797975656153714319">"Starten Sie zur Nutzung des Mobilfunknetzes Ihr Gerät neu."</string>
+    <string name="sim_added_message" msgid="7797975656153714319">"Starte zur Nutzung des Mobilfunknetzes dein Gerät neu."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Neu starten"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Uhrzeit festlegen"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum festlegen"</string>
@@ -1030,6 +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>
+    <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>
@@ -1048,7 +1065,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> nicht unterstützt"</string>
     <string name="ext_media_unsupported_notification_message" msgid="8789610369456474891">"<xliff:g id="NAME">%s</xliff:g> wird von diesem Gerät nicht unterstützt. Zum Einrichten in einem unterstützten Format tippen."</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> wurde unerwartet entfernt"</string>
-    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Trennen Sie die <xliff:g id="NAME">%s</xliff:g> vor dem Entfernen, um Datenverluste zu vermeiden."</string>
+    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Trenne die <xliff:g id="NAME">%s</xliff:g> vor dem Entfernen, um Datenverluste zu vermeiden."</string>
     <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"<xliff:g id="NAME">%s</xliff:g> wurde entfernt"</string>
     <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"<xliff:g id="NAME">%s</xliff:g> entfernt. Neuen Speicher einlegen"</string>
     <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"<xliff:g id="NAME">%s</xliff:g> wird gerade ausgeworfen…"</string>
@@ -1093,15 +1110,15 @@
     <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_footer" msgid="3125211343379376561">"Möchten Sie diese Anfrage zulassen?"</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>
     <string name="deny" msgid="2081879885755434506">"Ablehnen"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Berechtigung angefordert"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Berechtigung angefordert\nfür Konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
-    <string name="forward_intent_to_owner" msgid="1207197447013960896">"Sie verwenden diese App außerhalb Ihres Arbeitsprofils."</string>
-    <string name="forward_intent_to_work" msgid="621480743856004612">"Sie verwenden diese App in Ihrem Arbeitsprofil."</string>
+    <string name="forward_intent_to_owner" msgid="1207197447013960896">"Du verwendest diese App außerhalb deines Arbeitsprofils."</string>
+    <string name="forward_intent_to_work" msgid="621480743856004612">"Du verwendest diese App in deinem Arbeitsprofil."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Eingabemethode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisieren"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Bedienungshilfen"</string>
@@ -1149,7 +1166,7 @@
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Nein"</string>
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"Löschbegrenzung überschritten"</string>
-    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Es sind <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> gelöschte Elemente für <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, Konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>, vorhanden. Wie möchten Sie fortfahren?"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Es sind <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> gelöschte Elemente für <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, Konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>, vorhanden. Wie möchtest du fortfahren?"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"Elemente löschen"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Löschen rückgängig machen"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Im Moment nichts unternehmen"</string>
@@ -1187,7 +1204,7 @@
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Mit <xliff:g id="APPLICATION_NAME">%s</xliff:g> teilen"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Schieberegler: Berühren und halten"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Zum Entsperren den Finger über den Bildschirm ziehen"</string>
-    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Schließen Sie ein Headset an, um das Passwort gesprochen zu hören."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Schließe ein Headset an, um das Passwort gesprochen zu hören."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Zur Startseite navigieren"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Nach oben navigieren"</string>
@@ -1267,44 +1284,44 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Falsches Muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Falsches Passwort"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Falsche PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuchen Sie es in <xliff:g id="NUMBER">%1$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuche es in <xliff:g id="NUMBER">%1$d</xliff:g> Sekunden erneut."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Muster zeichnen"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM-PIN eingeben"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN eingeben"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"Passwort eingeben"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Die SIM-Karte ist jetzt deaktiviert. Geben Sie den PUK-Code ein, um fortzufahren. Weitere Informationen erhalten Sie von Ihrem Mobilfunkanbieter."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Weitere Informationen erhältst du von deinem Mobilfunkanbieter."</string>
     <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewünschten PIN-Code eingeben"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewünschten PIN-Code bestätigen"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-Karte wird entsperrt…"</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Falscher PIN-Code"</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Geben Sie eine 4- bis 8-stellige PIN ein."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Gib eine 4- bis 8-stellige PIN ein."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Der PUK-Code muss 8 Ziffern aufweisen."</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"Geben Sie den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Gib den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-Codes stimmen nicht überein"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zu viele Musterversuche"</string>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"Melden Sie sich zum Entsperren mit Ihrem Google-Konto an."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Melde dich zum Entsperren mit deinem Google-Konto an."</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"Nutzername (E-Mail)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Passwort"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Anmelden"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ungültiger Nutzername oder ungültiges Passwort"</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nutzernamen oder Passwort vergessen?\nBesuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nutzernamen oder Passwort vergessen?\nBesuche "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto wird geprüft…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Sie haben Ihre PIN <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird der Fernseher auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Der Fernseher wird nun auf die Werkseinstellungen zurückgesetzt."</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Wenn Sie es noch <xliff:g id="NUMBER_1">%2$d</xliff:g>-mal falsch eingeben, werden Sie aufgefordert, Ihren Fernseher mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du hast deine PIN <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du hast dein Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nVersuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird der Fernseher auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Der Fernseher wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Wenn du es noch <xliff:g id="NUMBER_1">%2$d</xliff:g>-mal falsch eingibst, wirst du aufgefordert, deinen Fernseher mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Entfernen"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Lautstärke über den Schwellenwert anheben?\n\nWenn Sie über längere Zeiträume hinweg Musik in hoher Lautstärke hören, kann dies Ihr Gehör schädigen."</string>
-    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Drücken Sie mit zwei Fingern, um die Bedienungshilfen zu aktivieren."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Lautstärke über den Schwellenwert anheben?\n\nWenn du über einen längeren Zeitraum Musik in hoher Lautstärke hörst, kann dies dein Gehör schädigen."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Drücke mit zwei Fingern, um die Bedienungshilfen zu aktivieren."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Bedienungshilfen aktiviert"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Bedienungshilfen abgebrochen"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1312,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>
@@ -1411,7 +1428,7 @@
     <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Neue PIN"</string>
     <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Neue PIN bestätigen"</string>
     <string name="restr_pin_create_pin" msgid="8017600000263450337">"PIN für das Ändern von Einschränkungen erstellen"</string>
-    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Die PINs stimmen nicht überein. Bitte versuchen Sie es erneut."</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Die PINs stimmen nicht überein. Bitte versuche es erneut."</string>
     <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Die PIN ist zu kurz. Sie muss mindestens 4 Ziffern umfassen."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
       <item quantity="other">In <xliff:g id="COUNT">%d</xliff:g> Sek. wiederholen</item>
@@ -1430,19 +1447,19 @@
     <string name="select_year" msgid="7952052866994196170">"Jahr auswählen"</string>
     <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> gelöscht"</string>
     <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
-    <string name="lock_to_app_toast" msgid="7570091317001980053">"Um die Fixierung dieses Bildschirms aufzuheben, berühren und halten Sie gleichzeitig \"Zurück\" und \"Übersicht\"."</string>
-    <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Um die Fixierung dieses Bildschirms aufzuheben, berühren und halten Sie \"Übersicht\"."</string>
+    <string name="lock_to_app_toast" msgid="7570091317001980053">"Um die Fixierung dieses Bildschirms aufzuheben, berühre und halte gleichzeitig \"Zurück\" und \"Übersicht\"."</string>
+    <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Um die Fixierung dieses Bildschirms aufzuheben, berühre und halte \"Übersicht\"."</string>
     <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Die App ist fixiert. Das Aufheben der Fixierung ist auf diesem Gerät nicht zulässig."</string>
     <string name="lock_to_app_start" msgid="6643342070839862795">"Bildschirm fixiert"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"Bildschirm gelöst"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Vor dem Beenden nach PIN fragen"</string>
     <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. Scrollen Sie 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="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 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>
@@ -1487,8 +1504,8 @@
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Wochenende"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Termin"</string>
     <string name="muted_by" msgid="6147073845094180001">"Stummgeschaltet durch <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
-    <string name="system_error_wipe_data" msgid="6608165524785354962">"Es liegt ein internes Problem mit Ihrem Gerät vor. Möglicherweise verhält es sich instabil, bis Sie es auf die Werkseinstellungen zurücksetzen."</string>
-    <string name="system_error_manufacturer" msgid="8086872414744210668">"Es liegt ein internes Problem mit Ihrem Gerät vor. Bitte wenden Sie sich diesbezüglich an den Hersteller."</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Es liegt ein internes Problem mit deinem Gerät vor. Möglicherweise verhält es sich instabil, bis du es auf die Werkseinstellungen zurücksetzt."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Es liegt ein internes Problem mit deinem Gerät vor. Bitte wende dich diesbezüglich an den Hersteller."</string>
     <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD-Anfrage wird in DIAL-Anfrage geändert."</string>
     <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD-Anfrage wird in SS-Anfrage geändert."</string>
     <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD-Anfrage wird in neue USSD-Anfrage geändert."</string>
@@ -1510,4 +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>
+    <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 8116b16..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Περιλαμβάνει προσωπικά δεδομένα, όπως είναι οι αριθμοί πιστωτικών καρτών και οι κωδικοί πρόσβασης."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ελέγξτε τη μεγέθυνση της οθόνης"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ελέγξτε το επίπεδο ζουμ και τη θέση της οθόνης."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Εκτέλεση κινήσεων"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Επιτρέπει το πάτημα, την ολίσθηση, το πλησίασμα και άλλες κινήσεις."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"απενεργοποίηση ή τροποποίηση γραμμής κατάστασης"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Επιτρέπει στην εφαρμογή να απενεργοποιεί τη γραμμή κατάστασης ή να προσθέτει και να αφαιρεί εικονίδια συστήματος."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ορισμός ως γραμμής κατάστασης"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 930c310..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Includes personal data such as credit card numbers and passwords."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Control display magnification"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Control the display\'s zoom level and positioning."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Miscellaneous"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but is currently prohibited."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the user limit has been reached."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" already exists on this device. Proceed anyway?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user for the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Proceed?"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 930c310..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Includes personal data such as credit card numbers and passwords."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Control display magnification"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Control the display\'s zoom level and positioning."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Miscellaneous"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but is currently prohibited."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the user limit has been reached."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" already exists on this device. Proceed anyway?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user for the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Proceed?"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 930c310..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Includes personal data such as credit card numbers and passwords."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Control display magnification"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Control the display\'s zoom level and positioning."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Miscellaneous"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but is currently prohibited."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the user limit has been reached."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" already exists on this device. Proceed anyway?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user for the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Proceed?"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 258ef33..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Incluye datos personales, como números de tarjeta de crédito y contraseñas."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controlar la ampliación de pantalla"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controla el posicionamiento y el nivel de zoom de la pantalla."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Usar gestos"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Permite presionar, deslizar, pellizcar y usar otros gestos."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"desactivar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que la aplicación inhabilite la barra de estado o que agregue y elimine íconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"aparecer en la barra de estado"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 9848bb6..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Incluye datos personales como números de tarjetas de crédito y contraseñas."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controla la ampliación de la pantalla"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controla el posicionamiento y el nivel de zoom de la pantalla."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Realizar gestos"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Puedes tocar y pellizcar la pantalla, deslizar el dedo y hacer otros gestos."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"inhabilitar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que la aplicación inhabilite la barra de estado o añada y elimine iconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"aparecer en la barra de estado"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 466bd5d..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sisaldab isiklikke andmeid, nt krediitkaardi numbreid ja paroole."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ekraani suurenduse juhtimine"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Saate juhtida ekraani suumitaset ja asendit."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Liigutuste tegemine"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Saate puudutada, pühkida, sõrmi kokku-lahku liigutada ja teisi liigutusi teha."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"keela või muuda olekuriba"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Võimaldab rakendusel keelata olekuriba või lisada ja eemaldada süsteemiikoone."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"olekuribana kuvamine"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 cdb8622..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Ez da salbuespenik egiten datu pertsonalekin, hala nola, kreditu-txartelen zenbakiekin eta pasahitzekin."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrolatu pantailaren zoom-maila"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolatu pantailaren zoom-maila eta kokapena."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Keinuak egin"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Sakatu, lerratu, atximurkatu eta beste hainbat keinu egin ditzake."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"Desgaitu edo aldatu egoera-barra"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Egoera-barra desgaitzea edo sistema-ikonoak gehitzea edo kentzea baimentzen die aplikazioei."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"Bihurtu egoera-barra"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 b0da5fe..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"اطلاعات شخصی مانند شماره کارت اعتباری و گذرواژه‌ها را لحاظ می‌کند."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"کنترل درشت‌نمایی نمایشگر"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"سطح و موقعیت بزرگ‌نمایی نمایشگر را کنترل کنید."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"اجرای اشاره‌ها"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"می‌توانید ضربه بزنید، انگشتتان را تند بکشید، انگشتانتان را به هم نزدیک یا از هم دور کنید و اشاره‌های دیگری اجرا کنید."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"غیرفعال کردن یا تغییر نوار وضعیت"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"‏به برنامه اجازه می‎دهد تا نوار وضعیت را غیرفعال کند یا نمادهای سیستم را اضافه یا حذف کند."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"نوار وضعیت باشد"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 f7db678..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sisältää henkilökohtaisia tietoja, kuten luottokortin numeroita ja salasanoja."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Näytön suurentamisen hallinnointi"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Hallinnoi näytön zoomaustasoa ja asettelua."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Eleiden käyttäminen"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Lupa napauttaa, pyyhkäistä, nipistää ja käyttää muita eleitä."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"poista tilapalkki käytöstä tai muokkaa tilapalkkia"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Antaa sovelluksen poistaa tilapalkin käytöstä ja lisätä tai poistaa järjestelmäkuvakkeita."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"sijaita tilapalkissa"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 50aed95..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclut des données personnelles telles que les numéros de cartes de paiement et les mots de passe."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Contrôler l\'agrandissement de l\'écran"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Contrôler le niveau de zoom et le positionnement de l\'écran."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Effectuer des gestes"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Peut toucher, balayer, pincer et effectuer d\'autres gestes."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"désactiver ou modifier la barre d\'état"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"servir de barre d\'état"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 33d2016..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclut des données personnelles telles que les numéros de cartes de paiement et les mots de passe."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Contrôler l\'agrandissement de l\'écran"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Contrôler le niveau de zoom et le positionnement de l\'écran"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Effectuer des gestes"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Permet d\'appuyer sur l\'écran, de le balayer, de le pincer et d\'effectuer d\'autres gestes."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"Désactivation ou modification de la barre d\'état"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"remplacer la barre d\'état"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 7947825..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclúe datos persoais como números e contrasinais de tarxetas de crédito."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controlar ampliación da pantalla"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o nivel do zoom e o posicionamento da pantalla"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Realizar xestos"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Podes tocar, pasar o dedo, beliscar e realizar outros xestos."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"desactivar ou modificar a barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite á aplicación desactivar a barra de estado ou engadir e eliminar as iconas do sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"actuar como a barra de estado"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 aa9478b..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ક્રેડિટ કાર્ડ નંબર્સ અને પાસવર્ડ્સ જેવો વ્યક્તિગત ડેટા શામેલ છે."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"પ્રદર્શન વિસ્તૃતિકરણ નિયંત્રિત કરો"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"પ્રદર્શનનું ઝૂમ સ્તર અને સ્થિતિનિર્ધારણ નિયંત્રિત કરો."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"હાવભાવ કરો"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ટૅપ, સ્વાઇપ, પિંચ કરી અને અન્ય હાવભાવ કરી શકે છે."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"સ્થિતિ બાર અક્ષમ કરો અથવા સંશોધિત કરો"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"એપ્લિકેશનને સ્થિતિ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"સ્થિતિ બાર થાઓ"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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-hi/strings.xml b/core/res/res/values-hi/strings.xml
index d3d1e2c..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"क्रेडिट कार्ड नंबर और पासवर्ड जैसा व्यक्तिगत डेटा शामिल होता है."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"प्रदर्शन आवर्धन नियंत्रित करें"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शन का ज़ूम स्‍तर और स्‍थिति निर्धारण नियंत्रित करें."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"हावभाव निष्पादित करें"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"इस सेवा के द्वारा टैप किया जा सकता है, स्वाइप किया जा सकता है, पिंच किया जा सकता है और अन्य हावभाव निष्पादित किए जा सकते हैं."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"स्‍थिति बार अक्षम या बदलें"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ऐप्स  को स्थिति बार अक्षम करने या सिस्‍टम आइकन को जोड़ने या निकालने देता है."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"स्‍थिति बार होने दें"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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-hr/strings.xml b/core/res/res/values-hr/strings.xml
index dc55c57..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>
@@ -257,6 +266,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Uključuje osobne podatke kao što su brojevi kreditnih kartica i zaporke."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrola uvećanja zaslona"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolira razinu zumiranja i položaj zaslona."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Izvođenje pokreta"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može dodirnuti, prijeći prstom, spojiti prste i izvoditi druge pokrete."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"onemogućavanje ili izmjena trake statusa"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Aplikaciji omogućuje onemogućavanje trake statusa ili dodavanje i uklanjanje sistemskih ikona."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"biti traka statusa"</string>
@@ -1037,6 +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>
+    <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>
@@ -1528,4 +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>
+    <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 3176c65..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Beleértve a személyes adatokat, például a hitelkártyaszámokat és jelszavakat."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"A kijelző nagyításának vezérlése"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"A kijelző nagyítási/kicsinyítési szintjének és pozíciójának vezérlése"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Kézmozdulatok végrehajtása"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Koppintás, ujjak gyors csúsztatása és összehúzása, illetve egyéb kézmozdulatok végrehajtása."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"állapotsor kikapcsolása vagy módosítása"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Lehetővé teszi az alkalmazás számára az állapotsor kikapcsolását, illetve rendszerikonok hozzáadását és eltávolítását."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"az állapotsor szerepének átvétele"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Vegyes"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Ön állította be ezen értesítések fontossági szintjét."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ez az üzenet a résztvevők miatt fontos."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"A(z) "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" alkalmazás egy új felhasználót szeretne megadni, ami jelenleg nem engedélyezett."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"A(z) "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" alkalmazás egy új felhasználót szeretne megadni, azonban Ön elérte a felhasználók számára vonatkozó felső korlátot."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"A(z) "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" alkalmazás egy új felhasználót szeretne megadni, de a(z) "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" fiók már létezik ezen az eszközön. Ettől függetlenül is folytatja?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"A(z) "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" alkalmazás egy új felhasználót szeretne hozzáadni a(z) "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" fiókhoz. Folytatja a műveletet?"</string>
 </resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index d72ee8d..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Ներառում է անձնական տվյալներ, ինչպիսիք են վարկային քարտերի համարները և գաղտնաբառերը:"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ցուցասարքի խոշորացման կառավարում"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ցուցասարքի մասշտաբավորման և դիրքավորման կառավարում:"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Կատարել ժեստեր"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Կարող է հպել, թերթել, պտղունցել և կատարել այլ ժեստեր:"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"անջատել կամ փոփոխել կարգավիճակի գոտին"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Թույլ է տալիս հավելվածին անջատել կարգավիճակի գոտին կամ ավելացնել ու հեռացնել համակարգի պատկերակները:"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"լինել կարգավիճակի գոտի"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 024eea4..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Meliputi data pribadi seperti nomor kartu kredit dan sandi."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Mengontrol perbesaran layar"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Mengontrol tingkat zoom dan pemosisian layar."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Melakukan isyarat"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Dapat mengetuk, menggesek, mencubit, dan melakukan isyarat lainnya."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"nonaktifkan atau ubah bilah status"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Mengizinkan apl menonaktifkan bilah status atau menambah dan menghapus ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"jadikan bilah status"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Lain-Lain"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Anda menyetel tingkat kepentingan notifikasi ini."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ini penting karena orang-orang yang terlibat."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mencoba menambahkan pengguna baru, tetapi saat ini dilarang."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mencoba menambahkan pengguna baru, tetapi batas jumlah pengguna telah tercapai."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mencoba menambahkan pengguna baru, tetapi akun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" sudah ada di perangkat. Tetap lanjutkan?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mencoba menambahkan pengguna baru untuk akun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Lanjutkan?"</string>
 </resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 240c715..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Felur í sér persónuleg gögn á borð við kreditkortanúmer og aðgangsorð."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Stilla skjástærð"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Stjórnaðu aðdrætti og afstöðu skjásins."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Nota bendingar"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Getur ýtt, strokið, fært fingur saman og gert ýmsar aðrar bendingar."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"slökkva á eða breyta stöðustiku"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Leyfir forriti að slökkva á stöðustikunni eða bæta við og fjarlægja kerfistákn."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"vera stöðustikan"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 ece503d..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sono inclusi dati personali come numeri di carte di credito e password."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controlla l\'ingrandimento del display"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlla il livello di zoom e la posizione del display."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Esegui gesti"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Consente di toccare, far scorrere, pizzicare ed eseguire altri gesti."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disattivare o modificare la barra di stato"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ruolo di barra di stato"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Vari"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Stabilisci tu l\'importanza di queste notifiche."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Importante a causa delle persone coinvolte."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sta cercando di aggiungere un nuovo utente, ma l\'app non è consentita."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sta cercando di aggiungere un nuovo utente, ma è stato raggiunto il limite massimo di utenti."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sta cercando di aggiungere un nuovo utente, ma l\'account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" esiste già su questo dispositivo. Continuare comunque?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sta cercando di aggiungere un nuovo utente per l\'account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuare?"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 144afc0..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"כולל נתונים אישיים כמו מספרי כרטיס אשראי וסיסמאות."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"שליטה בהגדלת התצוגה"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"קבע את המרחק מהתצוגה ואת מיקום התצוגה."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ביצוע תנועות"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"יכול להקיש, להחליק, לעשות תנועת צביטה ולבצע תנועות אחרות."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"השבת או שנה את שורת המצב"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"מאפשר לאפליקציה להשבית את שורת המצב או להוסיף ולהסיר סמלי מערכת."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"להיות שורת הסטטוס"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +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>
+    <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 edfab22..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"クレジットカードの番号やパスワードなどの個人データが含まれます。"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"画面の拡大の制御"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"画面のズームレベルと位置を制御します。"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"操作の実行"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"タップ、スワイプ、ピンチ、その他の操作を行えます。"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"ステータスバーの無効化や変更"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ステータスバーの無効化、システムアイコンの追加や削除をアプリに許可します。"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ステータスバーへの表示"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 ffdd31c..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"შეიცავს ისეთ პირად მონაცემებს, როგორიცაა საკრედიტო ბარათის ნომრები და პაროლები."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ერანის გადიდების მართვა"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ეკრანის მასშტაბირების დონისა და პოზიციის მართვა."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ჟესტების შესრულება"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"შეუძლია შეხება, გადაფურცვლა, მასშტაბირება და სხვა ჟესტების შესრულება."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"სტატუსის ზოლის გათიშვა ან ცვლილება"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"აპს შეეძლება სტატუსების ზოლის გათიშვა და სისტემის ხატულების დამატება/წაშლა."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"სტატუსის ზოლის ჩანაცვლება"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 ff58eaa..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Кредит карта нөмірі және кілтсөздер сияқты жеке деректерді қоса."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Дисплей ұлғайтуды басқару"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Дисплейдің масштабтау деңгейін және орналастыруды басқару."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Қимылдарды орындау"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Түртуге, сырғытуға, қысуға және басқа қимылдарды орындауға болады."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"күйін көрсету тақтасын өшіру немесе өзгерту"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Қолданбаға күй жолағын өшіруге немесе жүйелік белгішелерді қосуға және жоюға рұқсат береді."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"күй жолағы болу"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 261212f..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"រួម​បញ្ចូល​ទិន្នន័យ​ផ្ទាល់​ខ្លួន​ ដូចជា​លេខ​កាត​ឥណទាន និង​ពាក្យ​សម្ងាត់។"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"គ្រប់គ្រងការពង្រីកអេក្រង់"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"គ្រប់គ្រងការកំណត់ទីតាំង និងកម្រិតពង្រីករបស់អេក្រង់"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ធ្វើកាយវិការ"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"អាចប៉ះ អូស ច្បិច និងធ្វើកាយវិការផ្សេងទៀត"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"បិទ ឬ​កែ​របារ​ស្ថានភាព"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ឲ្យ​កម្មវិធី​បិទ​របារ​ស្ថានភាព ឬ​បន្ថែម និង​លុប​រូប​តំណាង​ប្រព័ន្ធ។"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ធ្វើជារបារស្ថានភាព"</string>
@@ -1032,6 +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>
+    <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>
@@ -1512,4 +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>
+    <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-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index f083702..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಸಂಖ್ಯೆಗಳು ಮತ್ತು ಪಾಸ್‌ವರ್ಡ್‌ಗಳಂತಹ ವೈಯಕ್ತಿಕ ಡೇಟಾವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ಪ್ರದರ್ಶನದ ವರ್ಧಕವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ಪ್ರದರ್ಶನದ ಝೂಮ್ ಮಟ್ಟ ಮತ್ತು ಸ್ಥಾನ ನಿರ್ಧಾರವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಮಾಡಿ"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ಟ್ಯಾಪ್ ಮಾಡಬಹುದು, ಸ್ವೈಪ್ ಮಾಡಬಹುದು, ಪಿಂಚ್ ಮಾಡಬಹುದು ಮತ್ತು ಇತರ ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಮಾಡಬಹುದು."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಇಲ್ಲವೇ ಮಾರ್ಪಡಿಸಿ"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಮತ್ತು ಸಿಸ್ಟಂ ಐಕಾನ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಾಗಿರಲು"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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-ko/strings.xml b/core/res/res/values-ko/strings.xml
index c8f08c7..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"신용카드 번호와 비밀번호 등의 개인 데이터를 포함합니다."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"디스플레이 배율 제어"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"디스플레이의 확대/축소 수준 및 위치를 제어합니다."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"동작 실행"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"탭, 스와이프, 확대/축소 및 기타 동작을 실행할 수 있습니다."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"상태 표시줄 사용 중지 또는 수정"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"앱이 상태 표시줄을 사용중지하거나 시스템 아이콘을 추가 및 제거할 수 있도록 허용합니다."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"상태 표시줄에 위치"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 4d84933..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Кредиттик карта номурлары жана сырсөздөр сыяктуу өздүк берилиштерди камтыйт."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Дисплейди чоңойтууну башкаруу"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Экрандагы сүрөттүн өлчөмүн өзгөртүү жана жайгаштыруу."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Жаңсоолорду аткаруу"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Таптап, серпип, чымчып жана башка жаңсоолорду аткара алат."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"абал тилкесин өчүрүү же өзгөртүү"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Колдонмого абал тилкесин өчүрүү же тутум сүрөтчөлөрүн кошуу же алып салуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"абал тилкесинин милдетин аткаруу"</string>
@@ -1031,6 +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>
+    <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>
@@ -1511,4 +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>
+    <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 12d67bb..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ຮວມທັງຂໍ້ມູນສ່ວນໂຕເຊັ່ນ: ເລກບັດເຄຣດິດ ແລະລະຫັດຜ່ານ."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ຄວບຄຸມການຂະຫຍາຍຈໍສະແດງຜົນ"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ຄວບຄຸມລະດັບການຊູມ ແລະການວາງຕຳແໜ່ງຂອງຈໍສະແດງຜົນ."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ດຳເນີນທ່າທາງຕ່າງໆ"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ສາມາດແຕະ, ປັດນີ້ວມື, ຢິບນິ້ວມື ແລະ ດຳເນີນທ່າທາງອື່ນ."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"ປິດການນນຳໃຊ້ ຫຼື ແກ້ໄຂແຖບສະຖານະ"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງແຖບສະຖານະ ຫຼືເພີ່ມ ແລະລຶບໄອຄອນລະບົບອອກໄດ້."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ເປັນ​ແຖບ​ສະ​ຖາ​ນະ"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 e35edd6..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Įtraukiami asmeniniai duomenys, pavyzdžiui, kredito kortelių numeriai ir slaptažodžiai."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ekrano didinimo valdymas"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Valdykite ekrano mastelio keitimo lygį ir pozicijos nustatymą."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Veiksmai gestais"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Galima paliesti, perbraukti, suimti ir atlikti kitus veiksmus gestais."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"išjungti ar keisti būsenos juostą"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Leidžiama programai neleisti būsenos juostos arba pridėti ir pašalinti sistemos piktogramas."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"būti būsenos juosta"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +1563,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Įvairūs"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Galite nustatyti šių pranešimų svarbą."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tai svarbu dėl susijusių žmonių."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"„<xliff:g id="APP">%1$s</xliff:g>“"</b>" bando pridėti naują naudotoją, tačiau šiuo metu tai draudžiama."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"„<xliff:g id="APP">%1$s</xliff:g>“"</b>" bando pridėti naują naudotoją, tačiau pasiektas naudotojų skaičiaus apribojimas."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"„<xliff:g id="APP">%1$s</xliff:g>“"</b>" bando pridėti naują naudotoją, tačiau paskyra "<b>"„<xliff:g id="ACCOUNT">%2$s</xliff:g>“"</b>" jau yra šiame įrenginyje. Vis tiek tęsti?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"„<xliff:g id="APP">%1$s</xliff:g>“"</b>" bando pridėti naują paskyros "<b>"„<xliff:g id="ACCOUNT">%2$s</xliff:g>“"</b>" naudotoją. Tęsti?"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index de02a4f..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>
@@ -257,6 +266,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Ietver personas datus, piemēram, kredītkartes numurus un paroles."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Displeja palielinājuma kontrole"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolējiet displeja tālummaiņas līmeni un pozicionēšanu."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Žestu izpilde"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Atbalsta pieskaršanos, vilkšanu, savilkšanu un citus žestus."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"atspējot vai pārveidot statusa joslu"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ļauj lietotnei atspējot statusa joslu vai pievienot un noņemt sistēmas ikonas."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"Būt par statusa joslu"</string>
@@ -1037,6 +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>
+    <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>
@@ -1528,4 +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>
+    <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-af/strings.xml b/core/res/res/values-mcc310-mnc160-af/strings.xml
new file mode 100644
index 0000000..72ca2f2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-af/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registreer by jou diensverskaffer"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-oproep"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-am/strings.xml b/core/res/res/values-mcc310-mnc160-am/strings.xml
new file mode 100644
index 0000000..5a6635c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-am/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-ar/strings.xml b/core/res/res/values-mcc310-mnc160-ar/strings.xml
new file mode 100644
index 0000000..c0e4229
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ar/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-az-rAZ/strings.xml b/core/res/res/values-mcc310-mnc160-az-rAZ/strings.xml
new file mode 100644
index 0000000..0c250cd
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-az-rAZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Operatorla qeydiyyatdan keçin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Zəngi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc160-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..d351d5e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-b+sr+Latn/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrujte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi pozivanje preko operatera %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-bg/strings.xml b/core/res/res/values-mcc310-mnc160-bg/strings.xml
new file mode 100644
index 0000000..88715f5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-bg/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-bn-rBD/strings.xml b/core/res/res/values-mcc310-mnc160-bn-rBD/strings.xml
new file mode 100644
index 0000000..0c3e816
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-bn-rBD/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-ca/strings.xml b/core/res/res/values-mcc310-mnc160-ca/strings.xml
new file mode 100644
index 0000000..89baf1b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ca/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
+  </string-array>
+  <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 per Wi-Fi amb %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-cs/strings.xml b/core/res/res/values-mcc310-mnc160-cs/strings.xml
new file mode 100644
index 0000000..3eb962e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-cs/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrace u operátora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Volání přes Wi-Fi: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-da/strings.xml b/core/res/res/values-mcc310-mnc160-da/strings.xml
new file mode 100644
index 0000000..8e401d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-da/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrer dig hos dit mobilselskab"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-opkald"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-de/strings.xml b/core/res/res/values-mcc310-mnc160-de/strings.xml
new file mode 100644
index 0000000..7b172d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-de/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registriere dich bei deinem Mobilfunkanbieter."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Anrufe über WLAN"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-el/strings.xml b/core/res/res/values-mcc310-mnc160-el/strings.xml
new file mode 100644
index 0000000..bfd09c0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-el/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc160-en-rAU/strings.xml
new file mode 100644
index 0000000..d4f59ed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-en-rAU/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc160-en-rGB/strings.xml
new file mode 100644
index 0000000..d4f59ed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-en-rGB/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-en-rIN/strings.xml
new file mode 100644
index 0000000..d4f59ed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-en-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc160-es-rUS/strings.xml
new file mode 100644
index 0000000..8930a3e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-es-rUS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Regístrate con tu proveedor."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Llamada por Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-es/strings.xml b/core/res/res/values-mcc310-mnc160-es/strings.xml
new file mode 100644
index 0000000..1aac00b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-es/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Regístrate con tu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Llamada Wi-Fi de %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
new file mode 100644
index 0000000..c3be115
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"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">"Operaatori %s WiFi-kõned"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-eu-rES/strings.xml b/core/res/res/values-mcc310-mnc160-eu-rES/strings.xml
new file mode 100644
index 0000000..93c4026
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-eu-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Erregistratu operadorearekin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi bidezko deiak"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-fa/strings.xml b/core/res/res/values-mcc310-mnc160-fa/strings.xml
new file mode 100644
index 0000000..247693a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fa/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-fi/strings.xml b/core/res/res/values-mcc310-mnc160-fi/strings.xml
new file mode 100644
index 0000000..aebdf71
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Rekisteröidy operaattorisi asiakkaaksi."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi-puhelut: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc160-fr-rCA/strings.xml
new file mode 100644
index 0000000..b0d21c2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fr-rCA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Inscrivez-vous auprès de votre fournisseur de services"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-fr/strings.xml b/core/res/res/values-mcc310-mnc160-fr/strings.xml
new file mode 100644
index 0000000..9fe787c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Inscrivez-vous auprès de votre opérateur."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Appels Wi-Fi %s"</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
new file mode 100644
index 0000000..f02d667
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 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 por wifi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-gu-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-gu-rIN/strings.xml
new file mode 100644
index 0000000..e218ee6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-gu-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-hi/strings.xml b/core/res/res/values-mcc310-mnc160-hi/strings.xml
new file mode 100644
index 0000000..23f4dc8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"अपने वाहक के साथ पंजीकृत करें"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s वाई-फ़ाई कॉलिंग"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-hr/strings.xml b/core/res/res/values-mcc310-mnc160-hr/strings.xml
new file mode 100644
index 0000000..956093a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrirajte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi pozivanje"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-hu/strings.xml b/core/res/res/values-mcc310-mnc160-hu/strings.xml
new file mode 100644
index 0000000..7dbf9e8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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-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 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-hy-rAM/strings.xml b/core/res/res/values-mcc310-mnc160-hy-rAM/strings.xml
new file mode 100644
index 0000000..aadc509
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hy-rAM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-in/strings.xml b/core/res/res/values-mcc310-mnc160-in/strings.xml
new file mode 100644
index 0000000..3640291
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-in/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Harap daftarkan ke operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Panggilan Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-is-rIS/strings.xml b/core/res/res/values-mcc310-mnc160-is-rIS/strings.xml
new file mode 100644
index 0000000..fd10da5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-is-rIS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Skráðu þig hjá símafyrirtækinu"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi símtöl"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-it/strings.xml b/core/res/res/values-mcc310-mnc160-it/strings.xml
new file mode 100644
index 0000000..d8479d3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-it/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 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">"Chiamate Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-iw/strings.xml b/core/res/res/values-mcc310-mnc160-iw/strings.xml
new file mode 100644
index 0000000..2aa3937
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-iw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"הירשם אצל הספק"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"‏שיחות Wi-Fi של %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ja/strings.xml b/core/res/res/values-mcc310-mnc160-ja/strings.xml
new file mode 100644
index 0000000..e589334
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ja/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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サービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"携帯通信会社に登録してください"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi通話(%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ka-rGE/strings.xml b/core/res/res/values-mcc310-mnc160-ka-rGE/strings.xml
new file mode 100644
index 0000000..2b8fd07
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ka-rGE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-kk-rKZ/strings.xml b/core/res/res/values-mcc310-mnc160-kk-rKZ/strings.xml
new file mode 100644
index 0000000..b4f2433
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-kk-rKZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-km-rKH/strings.xml b/core/res/res/values-mcc310-mnc160-km-rKH/strings.xml
new file mode 100644
index 0000000..1806fbc
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-km-rKH/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"ការហៅតាមរយៈ Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-kn-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-kn-rIN/strings.xml
new file mode 100644
index 0000000..43d942a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-kn-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-ko/strings.xml b/core/res/res/values-mcc310-mnc160-ko/strings.xml
new file mode 100644
index 0000000..9e13223
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ko/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-ky-rKG/strings.xml b/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml
new file mode 100644
index 0000000..8b88ac1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-lo-rLA/strings.xml b/core/res/res/values-mcc310-mnc160-lo-rLA/strings.xml
new file mode 100644
index 0000000..a5347a9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-lo-rLA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-lt/strings.xml b/core/res/res/values-mcc310-mnc160-lt/strings.xml
new file mode 100644
index 0000000..81b7488
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-lt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Užregistruokite pas operatorių"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"„%s“ „Wi-Fi“ skambinimas"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-lv/strings.xml b/core/res/res/values-mcc310-mnc160-lv/strings.xml
new file mode 100644
index 0000000..5d24c5f
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-lv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi zvani"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-mk-rMK/strings.xml b/core/res/res/values-mcc310-mnc160-mk-rMK/strings.xml
new file mode 100644
index 0000000..aea280e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-mk-rMK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-ml-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-ml-rIN/strings.xml
new file mode 100644
index 0000000..9e244eb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ml-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s വൈഫൈ കോളിംഗ്"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-mn-rMN/strings.xml b/core/res/res/values-mcc310-mnc160-mn-rMN/strings.xml
new file mode 100644
index 0000000..5b59d99
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-mn-rMN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-mr-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-mr-rIN/strings.xml
new file mode 100644
index 0000000..168c36b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-mr-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"आपल्या वाहकासह नोंदणी करा"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s वाय-फाय कॉलिंग"</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
new file mode 100644
index 0000000..74bd9d6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 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">"Panggilan Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-my-rMM/strings.xml b/core/res/res/values-mcc310-mnc160-my-rMM/strings.xml
new file mode 100644
index 0000000..ae87ae7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-my-rMM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"ဝိုင်ဖိုင်သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်စေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် ဝိုင်ဖိုင် ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s ဝိုင်ဖိုင် ခေါ်ဆိုမှု"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-nb/strings.xml b/core/res/res/values-mcc310-mnc160-nb/strings.xml
new file mode 100644
index 0000000..34357e1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-nb/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrer deg hos operatøren din"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-anrop"</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
new file mode 100644
index 0000000..8956249
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-nl/strings.xml b/core/res/res/values-mcc310-mnc160-nl/strings.xml
new file mode 100644
index 0000000..319f799
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-nl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registreren bij je provider"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Bellen via wifi van %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pa-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-pa-rIN/strings.xml
new file mode 100644
index 0000000..5641abe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pa-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-pl/strings.xml b/core/res/res/values-mcc310-mnc160-pl/strings.xml
new file mode 100644
index 0000000..1d916cb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Zarejestruj u operatora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Połączenia przez Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc160-pt-rBR/strings.xml
new file mode 100644
index 0000000..1c68cb1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pt-rBR/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s chamada 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
new file mode 100644
index 0000000..86dba8c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 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 Wi-Fi da %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pt/strings.xml b/core/res/res/values-mcc310-mnc160-pt/strings.xml
new file mode 100644
index 0000000..1c68cb1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ro/strings.xml b/core/res/res/values-mcc310-mnc160-ro/strings.xml
new file mode 100644
index 0000000..f2490d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ro/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Înregistrați-vă la operatorul dvs."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Apelare prin Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ru/strings.xml b/core/res/res/values-mcc310-mnc160-ru/strings.xml
new file mode 100644
index 0000000..9f2bc43
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ru/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Укажите оператора и зарегистрируйтесь"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Звонки по Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-si-rLK/strings.xml b/core/res/res/values-mcc310-mnc160-si-rLK/strings.xml
new file mode 100644
index 0000000..0c13341
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-si-rLK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-sk/strings.xml b/core/res/res/values-mcc310-mnc160-sk/strings.xml
new file mode 100644
index 0000000..3fe32f7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrujte sa so svojím operátorom"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Volanie siete Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sl/strings.xml b/core/res/res/values-mcc310-mnc160-sl/strings.xml
new file mode 100644
index 0000000..3818309
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registracija pri operaterju"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Klicanje prek Wi-Fi-ja (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sq-rAL/strings.xml b/core/res/res/values-mcc310-mnc160-sq-rAL/strings.xml
new file mode 100644
index 0000000..647cd03
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sq-rAL/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Regjistrohu me operatorin tënd celular"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Telefonatat me Wi-Fi nga %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sr/strings.xml b/core/res/res/values-mcc310-mnc160-sr/strings.xml
new file mode 100644
index 0000000..7f8381a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Региструјте се код мобилног оператера"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi позивање преко оператера %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sv/strings.xml b/core/res/res/values-mcc310-mnc160-sv/strings.xml
new file mode 100644
index 0000000..e72b3b7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrera dig hos operatören"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-samtal"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sw/strings.xml b/core/res/res/values-mcc310-mnc160-sw/strings.xml
new file mode 100644
index 0000000..08ee7536
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Jisajili na mtoa huduma wako"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Upigaji Simu kwa Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ta-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-ta-rIN/strings.xml
new file mode 100644
index 0000000..d6ea49c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ta-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s வைஃபை அழைப்பு"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-te-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-te-rIN/strings.xml
new file mode 100644
index 0000000..61f3929
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-te-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-th/strings.xml b/core/res/res/values-mcc310-mnc160-th/strings.xml
new file mode 100644
index 0000000..f1ff305
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-th/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ลงทะเบียนกับผู้ให้บริการ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"กำลังเรียก Wi-Fi ของ %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
new file mode 100644
index 0000000..380b410
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-tl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 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 Gamit ang Wi-Fi ng %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-tr/strings.xml b/core/res/res/values-mcc310-mnc160-tr/strings.xml
new file mode 100644
index 0000000..2cb1dc9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-tr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Operatörünüze kaydolun"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Kablosuz Çağrı"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-uk/strings.xml b/core/res/res/values-mcc310-mnc160-uk/strings.xml
new file mode 100644
index 0000000..9e4d94c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-uk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Зареєструйтеся в оператора"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Дзвінок через Wi-Fi від оператора %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ur-rPK/strings.xml b/core/res/res/values-mcc310-mnc160-ur-rPK/strings.xml
new file mode 100644
index 0000000..e617582
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ur-rPK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-uz-rUZ/strings.xml b/core/res/res/values-mcc310-mnc160-uz-rUZ/strings.xml
new file mode 100644
index 0000000..a951fc4
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-uz-rUZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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 orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi qo‘ng‘iroqlar"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-vi/strings.xml b/core/res/res/values-mcc310-mnc160-vi/strings.xml
new file mode 100644
index 0000000..8f68be6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-vi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </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 qua Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc160-zh-rCN/strings.xml
new file mode 100644
index 0000000..3b10a63
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zh-rCN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"向您的运营商注册"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s WLAN 通话功能"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc160-zh-rHK/strings.xml
new file mode 100644
index 0000000..a39b37c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zh-rHK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc160-zh-rTW/strings.xml
new file mode 100644
index 0000000..28690aa
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zh-rTW/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <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-zu/strings.xml b/core/res/res/values-mcc310-mnc160-zu/strings.xml
new file mode 100644
index 0000000..d08486d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<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">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s ukushaya kwe-Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160/strings.xml b/core/res/res/values-mcc310-mnc160/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200/strings.xml b/core/res/res/values-mcc310-mnc200/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210/strings.xml b/core/res/res/values-mcc310-mnc210/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220/strings.xml b/core/res/res/values-mcc310-mnc220/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc230/strings.xml b/core/res/res/values-mcc310-mnc230/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc230/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc240/strings.xml b/core/res/res/values-mcc310-mnc240/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc240/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc250/strings.xml b/core/res/res/values-mcc310-mnc250/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc250/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260-de/strings.xml b/core/res/res/values-mcc310-mnc260-de/strings.xml
index 3994bba..b9cbb48 100644
--- a/core/res/res/values-mcc310-mnc260-de/strings.xml
+++ b/core/res/res/values-mcc310-mnc260-de/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="7239039348648848288">"Um über WLAN telefonieren und Nachrichten senden zu können, bitten Sie zuerst Ihren Mobilfunkanbieter, diesen Dienst einzurichten. Aktivieren Sie die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
+    <item msgid="7239039348648848288">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="483847327467331298">"Registrieren Sie sich bei Ihrem Mobilfunkanbieter."</item>
+    <item msgid="483847327467331298">"Registriere dich bei deinem Mobilfunkanbieter."</item>
   </string-array>
     <string name="wfcSpnFormat" msgid="4982938551498609442">"%s Anrufe über WLAN"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc270/strings.xml b/core/res/res/values-mcc310-mnc270/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc270/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc310/strings.xml b/core/res/res/values-mcc310-mnc310/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc310/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc490/strings.xml b/core/res/res/values-mcc310-mnc490/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc490/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc660/strings.xml b/core/res/res/values-mcc310-mnc660/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc660/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc800/strings.xml b/core/res/res/values-mcc310-mnc800/strings.xml
new file mode 100644
index 0000000..526d08b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc800/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- WFC Operator Error Codes -->
+    <string-array name="wfcOperatorErrorCodes" translatable="false">
+        <item>REG09</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as alerts -->
+    <string-array name="wfcOperatorErrorAlertMessages">
+        <item>To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings.</item>
+    </string-array>
+    <!-- WFC Operator Error Messages showed as notifications -->
+    <string-array name="wfcOperatorErrorNotificationMessages">
+        <item>Register with your carrier</item>
+    </string-array>
+    <!-- Template for showing cellular network operator name while WFC is active -->
+    <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
+</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 96a29a5..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Опфаќа лични податоци како што се броеви на кредитни картички и лозинки."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Контролирајте го зголемувањето на екранот"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Контролирајте го нивото на зумирање и позиционирање на екранот."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Користете движења"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Може да допрете, повлечете, штипнете и да користите други движења."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"оневозможи или измени статусна лента"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Дозволува апликацијата да ја оневозможи статусната лента или да додава или отстранува системски икони."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"да стане статусна лента"</string>
@@ -1030,6 +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>
+    <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>
@@ -1512,4 +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>
+    <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 f6869e3..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ക്രെഡിറ്റ് കാർഡ് നമ്പറുകളും പാസ്‌വേഡുകളും പോലുള്ള വ്യക്തിഗത ഡാറ്റ ഉൾപ്പെടുന്നു."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ഡിസ്പ്ലേ മാഗ്നിഫിക്കേഷൻ നിയന്ത്രിക്കുക"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ഡിസ്പ്ലേയുടെ സൂം നിലയും പൊസിഷനിംഗും നിയന്ത്രിക്കുക."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ജെസ്‌റ്ററുകൾ നിർവഹിക്കുക"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ടാപ്പുചെയ്യാനോ സ്വൈപ്പുചെയ്യാനോ പിഞ്ചുചെയ്യാനോ മറ്റ് ജെസ്‌റ്ററുകൾ നിർവഹിക്കാനോ കഴിയും."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"സ്റ്റാറ്റസ് ബാർ പ്രവർത്തനരഹിതമാക്കുക അല്ലെങ്കിൽ പരിഷ്‌ക്കരിക്കുക"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"നില ബാർ പ്രവർത്തരഹിതമാക്കുന്നതിന് അല്ലെങ്കിൽ സിസ്‌റ്റം ഐക്കണുകൾ ചേർക്കുന്നതിനും നീക്കംചെയ്യുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"സ്റ്റാറ്റസ് ബാർ ആയിരിക്കുക"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 d982ece..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Кредит картын дугаар болон нууц үг зэрэг хувийн датаг агуулж байна."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Дэлгэцийн өсгөлтийг хянах"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Дэлгэцийн томруулах түвшин болон байршлыг хянах."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Зангах"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Товших, шудрах, жижигрүүлэх болон бусад зангааг хийх боломжтой."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"статус самбарыг идэвхгүй болгох болон өөрчлөх"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Апп нь статус самбарыг идэвхгүй болгох эсвэл систем дүрсийг нэмэх, хасах боломжтой."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"статусын хэсэг болох"</string>
@@ -1030,6 +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>
+    <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>
@@ -1508,4 +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>
+    <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 4087199..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"क्रेडिट कार्ड नंबर आणि संकेतशब्‍द यासारखा वैयक्तिक डेटा समाविष्‍ट करते."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"प्रदर्शन विस्तृतीकरण नियंत्रित करा"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शनाचा झूम स्तर आणि स्थिती निर्धारण नियंत्रित करा."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"जेश्चर करा"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"टॅप, स्वाइप, पिंच आणि इतर जेश्चर करू शकते."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टीम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अॅप ला अनुमती देते."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"स्टेटस बार होऊ द्या"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 0923e91..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Termasuk data peribadi seperti nombor kad kredit dan kata laluan."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kawal pembesaran paparan"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kawal tahap zum dan kedudukan paparan."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Lakukan gerak isyarat"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Boleh ketik, leret, cubit dan laksanakan gerak isyarat lain."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"lumpuhkan atau ubah suai bar status"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"jadi bar status"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 3ef7e6c..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"အရေးကြီးသော ကိုယ်ရေးအချက်အလက်များဖြစ်တဲ့ ခရက်ဒစ်ကဒ်နံပါတ်များနှင့် စကားဝှက်များ ပါဝင်ပါတယ်."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"မျက်နှာပြင် ချဲ့ခြင်းကို ထိန်းချုပ်ပါ"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"မျက်နှာပြင် ချဲ့ခြင်းနှင့် နေရာချထားခြင်းကို ထိန်းချုပ်ပါ"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"လက်ဟန်များ အသုံးပြုပါ"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"တို့ခြင်း၊ ပွတ်ဆွဲခြင်း၊ နှင့် အခြား လက်ဟန်များကို အသုံးပြုနိုင်ပါသည်။"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"အခြေအနေပြဘားအား အလုပ်မလုပ်ခိုင်းရန်သို့မဟုတ် မွမ်းမံရန်"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"appအား အခြေအနေပြ ဘားကို ပိတ်ခွင့် သို့မဟတ် စနစ် အိုင်ကွန်များကို ထည့်ခြင်း ဖယ်ရှားခြင်း ပြုလုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"အခြေအနေပြ ဘားဖြစ်ပါစေ"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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-nb/strings.xml b/core/res/res/values-nb/strings.xml
index cd65d85..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Dette omfatter personlige data, som kredittkortnumre og passord."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrollér forstørrelse for skjermen"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrollér zoomenivået og plasseringen for skjermen."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Gjøre bevegelser"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trykke, sveipe, klype og gjøre andre bevegelser."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"deaktivere eller endre statusfeltet"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Lar appen deaktivere statusfeltet eller legge til og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"vise appen i statusfeltet"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 301094b..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"व्यक्तिगत डेटा जस्तै क्रेडिट कार्ड नम्बरहरू र पासवर्डहरू समावेश गर्दछ।"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"प्रदर्शन आवर्धन नियन्त्रण गर्नुहोस्"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शनको जुम स्तर र स्थिति नियन्त्रण गर्नुहोस्।"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"इसाराहरू सम्बन्धी कार्य गर्नुहोस्"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ट्याप, स्वाइप गर्न, थिच्न र अन्य इसाराहरू सम्बन्धी कार्य गर्न सक्छ"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"स्थिति पट्टिलाई अक्षम वा संशोधित गर्नुहोस्"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"स्थिति पट्टि असक्षम पार्न वा प्रणाली आइकनहरू थप्न र हटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"वस्तुस्थिति पट्टी हुन दिनुहोस्"</string>
@@ -1036,6 +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>
+    <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>
@@ -1516,4 +1533,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>
+    <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-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1407991..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Omvat persoonlijke gegevens zoals creditcardnummers en wachtwoorden."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Schermvergroting bedienen"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Bedien het zoomniveau en de positionering van het scherm."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Gebaren uitvoeren"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan tikken, vegen, samenknijpen en andere gebaren uitvoeren."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"statusbalk uitschakelen of wijzigen"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Hiermee kan de app de statusbalk uitschakelen of systeempictogrammen toevoegen en verwijderen."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"de statusbalk zijn"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diversen"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Je stelt het belang van deze meldingen in."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrijk vanwege de betrokken mensen."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeert een nieuwe gebruiker toe te voegen, maar dit is momenteel niet toegestaan."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeert een nieuwe gebruiker toe te voegen, maar de gebruikerslimiet is al bereikt."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeert een nieuwe gebruiker toe te voegen, maar het account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" bestaat al op dit apparaat. Toch doorgaan?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeert een nieuwe gebruiker toe te voegen voor het account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Doorgaan?"</string>
 </resources>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 39f20f5..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ਇਸ ਵਿੱਚ ਨਿੱਜੀ ਡਾਟਾ ਸ਼ਾਮਲ ਹੈ ਜਿਵੇਂ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ ਅਤੇ ਪਾਸਵਰਡ।"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ਡਿਸਪਲੇ ਵੱਡਦਰਸ਼ੀ ਨੂੰ ਨਿਯੰਤ੍ਰਿਤ ਕਰੋ"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ਡਿਸਪਲੇ ਦੇ ਜ਼ੂਮ ਪੱਧਰ ਅਤੇ ਸਥਿਤੀ ਨੂੰ ਨਿਯੰਤ੍ਰਿਤ ਕਰੋ।"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ਸੰਕੇਤ ਕਰਦੀ ਹੈ"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ਟੈਪ ਕਰ ਸਕਦੀ ਹੈ, ਸਵਾਈਪ ਕਰ ਸਕਦੀ ਹੈ, ਪਿੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਹੋਰ ਸੰਕੇਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"ਸਥਿਤੀ ਬਾਰ ਅਸਮਰੱਥ ਬਣਾਓ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਬਾਰ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਉਣ ਜਾਂ ਸਿਸਟਮ ਆਈਕਨਾਂ ਨੂੰ ਜੋੜਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ਸਥਿਤੀ ਪੱਟੀ ਬਣਨ ਦਿਓ"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f3e50b5..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obejmuje informacje osobiste, takie jak numery kart kredytowych i hasła."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Regulowanie powiększenia ekranu"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Regulowanie poziomu i obszaru powiększenia ekranu."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Obsługa gestów"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Obsługuje kliknięcia, przesunięcia, ściągnięcia palców i inne gesty."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"wyłączanie lub zmienianie paska stanu"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Pozwala aplikacji na wyłączanie paska stanu oraz dodawanie i usuwanie ikon systemowych."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"działanie jako pasek stanu"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +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>
+    <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 89bbbe8..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclui dados pessoais, como números de cartão de crédito e senhas."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controlar ampliação da tela"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o posicionamento e nível de zoom da tela."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Fazer gestos"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Toque, deslize, faça gestos de pinça e faça outros gestos."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar a barra de status"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ser a barra de status"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 f559dbb..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclui dados pessoais, como números de cartões de crédito e palavras-passe."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controlar a ampliação do ecrã"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o nível de zoom e o posicionamento do ecrã."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Realizar gestos"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"É possível tocar, deslizar rapidamente, juntar os dedos e realizar outros gestos"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite à aplicação desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ser apresentada na barra de estado"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 89bbbe8..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclui dados pessoais, como números de cartão de crédito e senhas."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controlar ampliação da tela"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o posicionamento e nível de zoom da tela."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Fazer gestos"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Toque, deslize, faça gestos de pinça e faça outros gestos."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar a barra de status"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ser a barra de status"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 4086e69..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>
@@ -257,6 +266,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Include date personale, cum ar fi numere ale cardurilor de credit sau parole."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Controlați mărirea pe afișaj"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlați nivelul de zoom și poziționarea afișajului."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Folosiți gesturi"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Se poate atinge, glisa, ciupi și se pot folosi alte gesturi."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"dezactivare sau modificare bare de stare"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite aplicației să dezactiveze bara de stare sau să adauge și să elimine pictograme de sistem."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"să fie bara de stare"</string>
@@ -1037,6 +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>
+    <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>
@@ -1528,4 +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>
+    <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 ee39b83..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"В том числе личные данные, например номера кредитных карт и пароли."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Управлять масштабом изображения"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Управлять позиционированием и размером изображения на экране."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Жесты"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Может выполнять жесты нажатия, пролистывания, масштабирования и т. д."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"Отключение/изменение строки состояния"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Приложение сможет отключать строку состояния, а также добавлять и удалять системные значки."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"Замена строки состояния"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +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>
+    <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 5364c98..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ණයවරපත් අංක සහ මුරපද වැනි පුද්ගලික දත්ත ඇතුළත් වේ."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"සංදර්ශන විශාලන මට්ටම පාලනය කිරීම"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"සංදර්ශනයේ විශාලන මට්ටම සහ පිහිටීම පාලනය කිරීම."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"අභින සිදු කරන්න"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"තට්ටු කිරීමට, ස්වයිප් කිරීමට, පින්ච් කිරීමට, සහ වෙනත් අභින සිදු කිරීමට හැකිය."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"තත්ව තීරුව අබල කරන්න හෝ වෙනස් කරන්න"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"තත්ව තීරුව අක්‍රිය කිරීමට හෝ පද්ධති නිරූපක එකතු හෝ ඉවත් කිරීමට යෙදුමට අවසර දේ."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"තත්ත්ව තීරුව බවට පත්වීම"</string>
@@ -1032,6 +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>
+    <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>
@@ -1512,4 +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>
+    <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 90ccd54..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sledovanie zahŕňa osobné údaje ako sú čísla kreditných kariet a heslá."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ovládanie priblíženia obrazovky"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ovládajte úroveň priblíženia/oddialenia obrazovky a umiestnenie"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Gestá"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Je možné použiť klepnutie, prejdenie, stiahnutie prstami a ďalšie gestá."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"zakázanie alebo zmeny stavového riadka"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje aplikácii vypnúť stavový riadok alebo pridať a odstrániť systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"vydávanie sa za stavový riadok"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +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>
+    <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 4e9b1c5..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Vključuje osebne podatke, kot so številke kreditnih kartic in gesla."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Nadziranje povečave prikaza"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Nadziranje stopnje povečave in položaja prikaza."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Izvajanje potez"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Mogoče je izvajanje dotikov, vlečenja, primikanja in razmikanja prstov ter drugih potez."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"onemogočanje ali spreminjanje vrstice stanja"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Aplikacijam omogoča onemogočenje vrstice stanja ali dodajanje in odstranjevanje ikon sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"postane vrstica stanja"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +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>
+    <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 be9c709..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Përfshi të dhënat personale si numrat e kartave të kreditit si dhe fjalëkalimet."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrollo zmadhimin e ekranit"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrollo nivelin dhe pozicionimin e zmadhimit të ekranit."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Kryen gjeste"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Mund të trokasë, rrëshqasë, bashkojë gishtat dhe kryejë gjeste të tjera."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"çaktivizo ose modifiko shiritin e statusit"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Lejon aplikacionin të çaktivizojë shiritin e statusit dhe të heqë ikonat e sistemit."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"të bëhet shiriti i statusit"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 a3618ab..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>
@@ -257,6 +266,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Обухвата личне податке као што су бројеви кредитних картица и лозинке."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Управљај увећањем приказа"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Управља нивоом зумирања приказа и одређивањем положаја."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Обављање покрета"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Може да додирује, листа, скупља приказ и обавља друге покрете."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"онемогућавање или измена статусне траке"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"функционисање као статусна трака"</string>
@@ -1037,6 +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>
+    <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>
@@ -1528,4 +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>
+    <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 b07dc28..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Omfattar personuppgifter som kreditkortsnummer och lösenord."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Styr skärmförstoringen"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Styr skärmens zoomnivå och positionering."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Göra rörelser"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trycka, svepa, nypa och göra andra rörelser."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"inaktivera eller ändra statusfält"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Tillåter att appen inaktiverar statusfältet eller lägger till och tar bort systemikoner."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"visas i statusfältet"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 cf0063c..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inajumuisha data binafsi kama vile nambari za kadi ya mkopo na manenosiri."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Dhibiti ukuzaji wa onyesho"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Dhibiti kiwango cha kukuza na nafasi cha onyesho."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Tekeleza ishara"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Unaweza kugonga, kutelezesha kidole, kubana na kutekeleza ishara zingine."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"zima au rekebisha mwambaa hali"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa ikoni za mfumo."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"kuwa sehemu ya arifa"</string>
@@ -1032,6 +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>
+    <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>
@@ -1512,4 +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>
+    <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 ecefb77..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"கிரெடிட் கார்டு எண்கள் மற்றும் கடவுச்சொற்கள் போன்ற தனிப்பட்ட தகவலும் உள்ளடங்கும்."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"திரையின் உருப்பெருக்கத்தைக் கட்டுப்படுத்துதல்"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"திரையின் ஜூம் அளவையும் நிலையையும் கட்டுப்படுத்தலாம்."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"சைகைகளைச் செயல்படுத்துதல்"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"தட்டலாம், ஸ்வைப் செய்யலாம், பின்ச் செய்யலாம் மற்றும் பிற சைகைகளைச் செயல்படுத்தலாம்."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"நிலைப் பட்டியை முடக்குதல் அல்லது மாற்றுதல்"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"நிலைப் பட்டியை முடக்க அல்லது முறைமையில் ஐகான்களைச் சேர்க்க மற்றும் அகற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"நிலைப் பட்டியில் இருக்கும்"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 b1bccd2..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"క్రెడిట్ కార్డు నంబర్‌లు మరియు పాస్‌వర్డ్‌ల వంటి వ్యక్తిగత డేటాను కలిగి ఉంటుంది."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"డిస్‌ప్లే మాగ్నిఫికేషన్‌ను నియంత్రించండి"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"డిస్‌ప్లే జూమ్ స్థాయి మరియు స్థానాన్ని నియంత్రిస్తుంది."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"సంజ్ఞలను చేయడం"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"నొక్కగలరు, స్వైప్ చేయగలరు, స్క్రీన్‌పై రెండు వేళ్లను ఉంచి ఆ వేళ్లను దగ్గరకు లేదా దూరానికి లాగగలరు మరియు ఇతర సంజ్ఞలను చేయగలరు."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"స్థితి బార్‌ను నిలిపివేయడం లేదా సవరించడం"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"స్థితి బార్‌ను నిలిపివేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"స్థితి పట్టీగా ఉండటం"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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-television/config.xml b/core/res/res/values-television/config.xml
index 3435474..0f98cfb 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -23,4 +23,12 @@
 
     <!-- Flags enabling default window features. See Window.java -->
     <bool name="config_defaultWindowFeatureOptionsPanel">false</bool>
+
+    <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
+    <string translatable="false" name="config_defaultPictureInPictureBounds">"1420 100 1820 325"</string>
+
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, when the PIP
+         is located in center. -->
+    <string translatable="false" name="config_centeredPictureInPictureBounds">"600 331 1320 749"</string>
+
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0b8e60d..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"รวมถึงข้อมูลส่วนบุคคล เช่น หมายเลขบัตรเครดิตและรหัสผ่าน"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ควบคุมการขยายการแสดงผล"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ควบคุมระดับการซูมและการวางตำแหน่งของการแสดงผล"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ทำท่าทางสัมผัส"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"สามารถแตะ เลื่อน บีบ และทำท่าทางสัมผัสอื่นๆ"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"ปิดการใช้งานหรือแก้ไขแถบสถานะ"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"อนุญาตให้แอปพลิเคชันปิดใช้งานแถบสถานะหรือเพิ่มและนำไอคอนระบบออก"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"เป็นแถบสถานะ"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 02a3587..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"May kasamang personal na data tulad ng mga numero ng credit card at password."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrolin ang pag-magnify ng display"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolin ang antas ng pag-zoom at pagpoposisyon ng display."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Magsagawa ng mga galaw"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"May kakayahang mag-tap, mag-swipe, mag-pinch at magsagawa ng iba pang mga galaw."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"huwag paganahin o baguhin ang status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Pinapayagan ang app na huwag paganahin ang status bar o magdagdag at mag-alis ng mga icon ng system."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"maging status bar"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 283bcebb..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Kredi kartı ve şifre gibi kişisel bilgiler içerir."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ekran büyütecini kontrol et"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ekranın yakınlaştırma seviyesini ve konumunu kontrol edin."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Haraketleri yapma"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Hafifçe dokunabilir, hızlıca kaydırabilir, sıkıştırabilir ve diğer hareketleri yapabilirsiniz."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"durum çubuğunu devre dışı bırak veya değiştir"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"durum çubuğunda olma"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 fce4cc3..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>
@@ -258,6 +267,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Включає особисті дані, як-от номери кредитних карток і паролі."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Контролювати збільшення екрана"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Контролювати масштаб і розташування екрана."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Виконання жестів"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Можна торкатися, проводити пальцем, стискати пальці та виконувати інші жести."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"вимикати чи змін. рядок стану"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Дозволяє програмі вимикати рядок стану чи додавати та видаляти піктограми системи."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"відображатися як рядок стану"</string>
@@ -1044,6 +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>
+    <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>
@@ -1546,4 +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>
+    <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-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 519f42b..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"اس میں ذاتی ڈیٹا جیسے کریڈٹ کارڈ نمبرز اور پاس ورڈز شامل ہیں۔"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ڈسپلے بڑا کرنے کے عمل کو کنٹرول کریں"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ڈسپلے کے زوم کی سطح اور پوزیشن کو کنٹرول کریں۔"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"اشارے انجام دیں"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"تھپتھپانا، سوائپ کرنا، چٹکی بھرنا اور دیگر اشارے انجام دے سکتی ہے"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"بطور اسٹیٹس بار کام لیں"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 e90d921..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Bunga kredit karta raqamlari va parollar kabi shaxsiy ma’lumotlar kiradi."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Ekranni kattalashtirishni boshqarish"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ekranni kattalashtirish darajasi va joylashuvini boshqaradi."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Imo-ishoralar bilan boshqarish"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Bosish, surish; jipslashtirish va boshqa imo-ishoralarni amalga oshirish mumkin."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"holat panelini o‘zgartirish yoki o‘chirish"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ilova holat panelini o‘chirib qo‘yishi hamda tizim ikonkalarini qo‘shishi yoki olib tashlashi mumkin."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"holat qatorida ko‘rinishi"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 31e090b..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Bao gồm dữ liệu cá nhân chẳng hạn như số thẻ tín dụng và mật khẩu."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kiểm soát thu phóng màn hình"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kiểm soát vị trí và mức thu phóng của màn hình."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Thực hiện cử chỉ"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Có thể nhấn, vuốt, chụm và thực hiện các cử chỉ khác."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"trở thành thanh trạng thái"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Khác"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Bạn đặt tầm quan trọng của các thông báo này."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Thông báo này quan trọng vì những người có liên quan."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" đang cố thêm người dùng mới nhưng hiện không được cho phép."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" đang cố thêm người dùng mới nhưng đã đạt đến giới hạn người dùng."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" đang cố thêm người dùng mới nhưng tài khoản "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" đã tồn tại trên thiết bị này. Vẫn tiếp tục?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" đang cố thêm người dùng mới cho tài khoản "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Tiếp tục?"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index c5cd59a..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"包含个人数据,例如信用卡号和密码。"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"控制显示内容放大功能"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"控制显示内容的缩放级别和位置。"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"执行手势"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"可执行点按、滑动、双指张合等手势。"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"停用或修改状态栏"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"允许应用停用状态栏或者增删系统图标。"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"用作状态栏"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 36ba2ad6..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"包括個人資料,如信用卡號碼和密碼。"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"控制顯示屏的放大功能"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"控制顯示屏的縮放程度和位置。"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"執行手勢"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"可以輕按、快速滑動和兩指縮放,並執行其他手勢。"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"停用或修改狀態列"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"成為狀態列"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +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>
+    <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 72ea523..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"包括個人資料,如信用卡號碼和密碼。"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"控管顯示畫面放大功能"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"控管顯示畫面的縮放等級和位置。"</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"使用手勢"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"可使用輕按、滑動和雙指撥動等手勢。"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"停用或變更狀態列"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"以狀態列顯示"</string>
@@ -521,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>
@@ -656,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>
@@ -684,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>
@@ -697,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>
@@ -710,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>
@@ -731,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>
@@ -1030,6 +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>
+    <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>
@@ -1291,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>
@@ -1436,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>
@@ -1510,4 +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>
+    <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 bee7eea..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>
@@ -256,6 +265,8 @@
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Kufaka phakathi idatha yomuntu siqu efana nezinombolo zekhadi lesikweletu namaphasiwedi."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Lawula ukulungiswa kwesibonisi"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Lawula ileveli yokusondeza yesibonisi nendawo."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Yenza ukuthinta"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Ingathepha, iswayiphe, incinze, futhi yenze okunye ukuthintwa."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"khubaza noma guqula ibha yomumo"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ivumela uhlelo lokusebenza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"yiba yibha yesimo"</string>
@@ -1030,6 +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>
+    <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>
@@ -1510,4 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Okwahlukahlukene"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Usethe ukubaluleka kwalezi zaziso."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Lokhu kubalulekile ngenxa yabantu ababandakanyekayo."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" izama ukungeza umsebenzisi omusha, kodwa okwamanje inqatshelewe."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" izama ukungeza umsebenzisi omusha, kodwa umkhawulo womsebenzisi ufinyelelwe."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" izama ukungeza umsebenzisi omusha, kodwa i-akhawunti "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" isivele ikhona kule divayisi. Qhubeka noma kunjalo?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" izama ukungeza umsebenzisi omusha we-akhawunti "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Qhubeka?"</string>
 </resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 58a77e8..6eba78a 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1748,6 +1748,10 @@
         <attr name="isolatedProcess" format="boolean" />
         <attr name="singleUser" />
         <attr name="encryptionAware" />
+        <!-- If the service is an {@link android.R.attr#isolatedProcess} service, this permits a
+             client to bind to the service as if it were running it its own package.  The service
+             must also be {@link android.R.attr#exported} if this flag is set. -->
+        <attr name="externalService" format="boolean" />
     </declare-styleable>
 
     <!-- The <code>receiver</code> tag declares an
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 58c4046..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
@@ -413,22 +441,29 @@
     <!-- Boolean indicating whether or not wifi firmware debugging is enabled -->
     <bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">true</bool>
 
+    <!-- Boolean indicating whether or not wifi should turn off when emergency call is made -->
+    <bool translatable="false" name="config_wifi_turn_off_during_emergency_call">false</bool>
+
     <!-- Integer specifying the basic autojoin parameters -->
     <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_threshold">-65</integer>
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_factor">5</integer>
+    <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_factor">40</integer>
     <integer translatable="false" name="config_wifi_framework_current_association_hysteresis_high">16</integer>
     <integer translatable="false" name="config_wifi_framework_current_association_hysteresis_low">10</integer>
     <integer translatable="false" name="config_wifi_framework_5GHz_preference_penalty_threshold">-75</integer>
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_penalty_factor">2</integer>
-
+    <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_OFFSET">85</integer>
+    <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_SLOPE">4</integer>
+    <integer translatable="false" name="config_wifi_framework_SAME_BSSID_AWARD">24</integer>
+    <integer translatable="false" name="config_wifi_framework_LAST_SELECTION_AWARD">480</integer>
+    <integer translatable="false" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD">40</integer>
+    <integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
     <!-- Integer parameters of the wifi to cellular handover feature
          wifi should not stick to bad networks -->
     <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz">-72</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz">-60</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz">-87</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz">-77</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz">-65</integer>
+    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz">-70</integer>
+    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz">-57</integer>
+    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz">-85</integer>
+    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz">-73</integer>
+    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz">-60</integer>
     <integer translatable="false" name="config_wifi_framework_wifi_score_bad_link_speed_24">6</integer>
     <integer translatable="false" name="config_wifi_framework_wifi_score_bad_link_speed_5">12</integer>
     <integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_24">24</integer>
@@ -502,7 +537,7 @@
     <integer translatable="false" name="config_wifi_framework_network_black_list_min_time_milli">120000</integer>
 
     <!-- Integer indicating RSSI boost given to current network -->
-    <integer translatable="false" name="config_wifi_framework_current_network_boost">25</integer>
+    <integer translatable="false" name="config_wifi_framework_current_network_boost">16</integer>
 
     <!-- Integer indicating how to handle beacons with uninitialized RSSI value of 0 -->
     <integer translatable="false" name="config_wifi_framework_scan_result_rssi_level_patchup_value">-85</integer>
@@ -644,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.
@@ -974,6 +998,7 @@
             0 - Nothing
             1 - Recent apps view in SystemUI
             2 - Launch assist intent
+            3 - Start picture-in-picture (PIP) or launch PIP UI
          This needs to match the constants in
          policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
     -->
@@ -1969,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
@@ -2354,6 +2379,9 @@
          (range of 18 - 21 kHz). -->
     <bool name="config_supportSpeakerNearUltrasound">true</bool>
 
+    <!-- Whether the Unprocessed audio source supports the required frequency range and level -->
+    <bool name="config_supportAudioSourceUnprocessed">false</bool>
+
     <!-- Flag indicating device support for EAP SIM, AKA, AKA' -->
     <bool name="config_eap_sim_based_auth_supported">true</bool>
 
@@ -2411,6 +2439,10 @@
     <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
     <string translatable="false" name="config_defaultPictureInPictureBounds">"0 0 100 100"</string>
 
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, when the PIP
+         is located in center. -->
+    <string translatable="false" name="config_centeredPictureInPictureBounds">"0 0 300 300"</string>
+
     <!-- Controls the snap mode for the docked stack divider
              0 - 3 snap targets: left/top has 16:9 ratio, 1:1, and right/bottom has 16:9 ratio
              1 - 3 snap targets: fixed ratio, 1:1, (1 - fixed ratio)
@@ -2421,4 +2453,13 @@
     <!-- List of comma separated package names for which we the system will not show crash, ANR,
          etc. dialogs. -->
     <string translatable="false" name="config_appsNotReportingCrashes"></string>
+
+    <!-- Inactivity threshold (in milliseconds) used in JobScheduler. JobScheduler will consider
+         the device to be "idle" after being inactive for this long. -->
+    <integer name="config_jobSchedulerInactivityIdleThreshold">4260000</integer>
+    <!-- The alarm window (in milliseconds) that JobScheduler uses to enter the idle state -->
+    <integer name="config_jobSchedulerIdleWindowSlop">300000</integer>
+
+    <!-- If true, all guest users created on the device will be ephemeral. -->
+    <bool name="config_guestUserEphemeral">false</bool>
 </resources>
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/public.xml b/core/res/res/values/public.xml
index acea461..c883b1f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2689,6 +2689,7 @@
     <public type="attr" name="tickMarkTint" />
     <public type="attr" name="tickMarkTintMode" />
     <public type="attr" name="canPerformGestures" />
+    <public type="attr" name="externalService" />
 
     <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
     <public type="style" name="Widget.Material.SeekBar.Discrete" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 997371e..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>
@@ -2899,6 +2894,19 @@
     <!-- Message of notification shown when ADB is actively connected to the phone. -->
     <string name="adb_active_notification_message">Touch to disable USB debugging.</string>
 
+    <!-- Title of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. -->
+    <string name="share_remote_bugreport_notification_title">Share bug report with admin?</string>
+    <!-- Message of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. -->
+    <string name="share_remote_bugreport_notification_message">Your IT admin requested a bug report to help troubleshoot</string>
+    <!-- Acceptance label of notification shown to ask for user consent for sharing the remote bugreport. -->
+    <string name="share_remote_bugreport_notification_accept">ACCEPT</string>
+    <!-- Decline label of notification shown to ask for user consent for sharing the remote bugreport. -->
+    <string name="share_remote_bugreport_notification_decline">DECLINE</string>
+    <!-- Title of notification shown for remote bugreport progress. -->
+    <string name="remote_bugreport_progress_notification_title">Taking bug report\u2026</string>
+    <!-- Message of notification shown for remote bugreport progress. User can cancel the bugreport -->
+    <string name="remote_bugreport_progress_notification_message_can_cancel">Touch to cancel</string>
+
     <!-- Used to replace %s in urls retreived from the signin server with locales.  For Some        -->
     <!-- devices we don't support all the locales we ship to and need to replace the '%s' with a    -->
     <!-- locale string based on mcc values.  By default (0-length string) we don't replace the %s   -->
@@ -2911,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>
@@ -4129,4 +4137,31 @@
 
     <string name="importance_from_topic">You set the importance of these notifications.</string>
     <string name="importance_from_person">This is important because of the people involved.</string>
+
+    <!-- Message to user that app trying to create user is not allowed to due to restrictions. [CHAR LIMIT=none] -->
+    <string name="user_creation_cannot_add"><b><xliff:g id="app" example="Gmail">%1$s</xliff:g></b> is trying to add a new user, but is currently prohibited.</string>
+    <!-- Message to user that app trying to create user is not allowed to due to user limit being reached. [CHAR LIMIT=none] -->
+    <string name="user_creation_cannot_add_any_more"><b><xliff:g id="app" example="Gmail">%1$s</xliff:g></b> is trying to add a new user, but the user limit has been reached.</string>
+    <!-- Message to user that app trying to create user for an account that already exists. [CHAR LIMIT=none] -->
+    <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 3d5f6ab..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">
@@ -877,7 +876,6 @@
 
     <style name="Widget.Material.ContextPopupMenu" parent="Widget.Material.ListPopupWindow">
         <item name="overlapAnchor">true</item>
-        <item name="popupEnterTransition">@null</item>
     </style>
 
     <style name="Widget.Material.ActionButton">
@@ -995,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>
@@ -1017,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>
@@ -1061,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 706dd20..9023dd4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -300,17 +300,26 @@
   <java-symbol type="bool" name="config_wifi_enable_5GHz_preference" />
   <java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
   <java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
+  <java-symbol type="bool" name="config_wifi_turn_off_during_emergency_call" />
   <java-symbol type="bool" name="config_supportMicNearUltrasound" />
   <java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
+  <java-symbol type="bool" name="config_supportAudioSourceUnprocessed" />
   <java-symbol type="bool" name="config_freeformWindowManagement" />
+  <java-symbol type="bool" name="config_guestUserEphemeral" />
   <java-symbol type="string" name="config_defaultPictureInPictureBounds" />
+  <java-symbol type="string" name="config_centeredPictureInPictureBounds" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_factor" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
   <java-symbol type="integer" name="config_wifi_framework_current_association_hysteresis_high" />
   <java-symbol type="integer" name="config_wifi_framework_current_association_hysteresis_low" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_factor" />
+  <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_OFFSET" />
+  <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_SLOPE" />
+  <java-symbol type="integer" name="config_wifi_framework_SAME_BSSID_AWARD" />
+  <java-symbol type="integer" name="config_wifi_framework_LAST_SELECTION_AWARD" />
+  <java-symbol type="integer" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD" />
+  <java-symbol type="integer" name="config_wifi_framework_SECURITY_AWARD" />
   <java-symbol type="integer" name="config_wifi_disconnected_short_scan_interval" />
   <java-symbol type="integer" name="config_wifi_disconnected_long_scan_interval" />
   <java-symbol type="integer" name="config_wifi_associated_short_scan_interval" />
@@ -930,6 +939,10 @@
   <java-symbol type="string" name="time_picker_increment_minute_button" />
   <java-symbol type="string" name="time_picker_increment_set_pm_button" />
   <java-symbol type="string" name="upload_file" />
+  <java-symbol type="string" name="user_creation_cannot_add" />
+  <java-symbol type="string" name="user_creation_cannot_add_any_more" />
+  <java-symbol type="string" name="user_creation_account_exists" />
+  <java-symbol type="string" name="user_creation_adding" />
   <java-symbol type="string" name="user_switched" />
   <java-symbol type="string" name="user_switching_message" />
   <java-symbol type="string" name="user_logging_out_message" />
@@ -1580,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" />
@@ -1758,6 +1770,12 @@
   <java-symbol type="string" name="accessibility_binding_label" />
   <java-symbol type="string" name="adb_active_notification_message" />
   <java-symbol type="string" name="adb_active_notification_title" />
+  <java-symbol type="string" name="share_remote_bugreport_notification_title" />
+  <java-symbol type="string" name="share_remote_bugreport_notification_message" />
+  <java-symbol type="string" name="share_remote_bugreport_notification_accept" />
+  <java-symbol type="string" name="share_remote_bugreport_notification_decline" />
+  <java-symbol type="string" name="remote_bugreport_progress_notification_title" />
+  <java-symbol type="string" name="remote_bugreport_progress_notification_message_can_cancel" />
   <java-symbol type="string" name="aerr_application" />
   <java-symbol type="string" name="aerr_process" />
   <java-symbol type="string" name="aerr_process_silence" />
@@ -2252,6 +2270,9 @@
 
   <java-symbol type="integer" name="config_defaultNightMode" />
 
+  <java-symbol type="integer" name="config_jobSchedulerInactivityIdleThreshold" />
+  <java-symbol type="integer" name="config_jobSchedulerIdleWindowSlop" />
+
   <java-symbol type="style" name="Animation.ImmersiveModeConfirmation" />
 
   <java-symbol type="integer" name="config_screen_magnification_multi_tap_adjustment" />
@@ -2426,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/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 5f1f927..77d2ada 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -33,6 +33,9 @@
          and http://mobilcent.com/info-worldwide.asp and extracted from:
          http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
 
+    <!-- Arab Emirates -->
+    <shortcode country="ae" free="3214|1017" />
+
     <!-- Albania: 5 digits, known short codes listed -->
     <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
 
@@ -43,7 +46,7 @@
     <shortcode country="at" pattern="11\\d{4}" premium="09.*" free="116\\d{3}" />
 
     <!-- Australia: 6 or 8 digits starting with "19" -->
-    <shortcode country="au" pattern="19(?:\\d{4}|\\d{6})" premium="19998882" />
+    <shortcode country="au" pattern="19(?:\\d{4}|\\d{6})" premium="19998882|19944444" />
 
     <!-- Azerbaijan: 4-5 digits, known premium codes listed -->
     <shortcode country="az" pattern="\\d{4,5}" premium="330[12]|87744|901[234]|93(?:94|101)|9426|9525" />
@@ -58,10 +61,10 @@
     <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
 
     <!-- Canada: 5-6 digits -->
-    <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188" />
+    <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" />
 
     <!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
-    <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111" />
+    <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" />
 
     <!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
          http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
@@ -75,7 +78,7 @@
     <shortcode country="cz" premium="9\\d{6,7}" free="116\\d{3}" />
 
     <!-- Germany: 4-5 digits plus 1232xxx (premium codes from http://www.vodafone.de/infofaxe/537.pdf and http://premiumdienste.eplus.de/pdf/kodex.pdf), plus EU. To keep the premium regex from being too large, it only includes payment processors that have been used by SMS malware, with the regular pattern matching the other premium short codes. -->
-    <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}|81214|81215" />
+    <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}|81214|81215|47529" />
 
     <!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers -->
     <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}" />
@@ -89,7 +92,7 @@
     <shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}" />
 
     <!-- Finland: 5-6 digits, premium 0600, 0700: http://en.wikipedia.org/wiki/Telephone_numbers_in_Finland -->
-    <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}" />
+    <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}|14789" />
 
     <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
          http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements,
@@ -122,9 +125,15 @@
          http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf -->
     <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}" />
 
+    <!-- Japan: 8083 used by SOFTBANK_DCB_2 -->
+    <shortcode country="jp" free="8083" />
+
     <!-- Kyrgyzstan: 4 digits, known premium codes listed -->
     <shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" />
 
+    <!-- Korea: http://www.smsideatechnosolutions.com/chhattisgarh/korea/sms-short-code.html -->
+    <shortcode country="kr" pattern="\\d{4,7}" free="\\*9712|\\*9090|##900" />
+
     <!-- Kazakhstan: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-kazakhstan/ -->
     <shortcode country="kz" pattern="\\d{4}" premium="335[02]|4161|444[469]|77[2359]0|8444|919[3-5]|968[2-5]" />
 
@@ -151,27 +160,33 @@
     <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" />
 
     <!-- New Zealand: 3-4 digits, known premium codes listed -->
-    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995" />
+    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" />
+
+    <!-- Philippines -->
+    <shortcode country="ph" free="2147" />
 
     <!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU -->
-    <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}" />
+    <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}|8012" />
 
     <!-- Portugal: 5 digits, plus EU:
          http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
     <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}" />
 
     <!-- Romania: 4 digits, plus EU: http://www.simplus.ro/en/resources/glossary-of-terms/ -->
-    <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}" />
+    <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}|3654" />
 
     <!-- Russia: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-russia/ -->
-    <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)" />
+    <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)|8424" />
+
+    <!-- Saudi Arabia -->
+    <shortcode country="sa" free="8145" />
 
     <!-- Sweden: 5 digits (72xxx), plus EU: http://www.viatel.se/en/premium-sms/ -->
     <shortcode country="se" premium="72\\d{3}" free="116\\d{3}" />
 
     <!-- Singapore: 5 digits: http://clients.txtnation.com/entries/306442-singapore-premium-sms-short-code-requirements
          Free government directory info at 74688: http://app.sgdi.gov.sg/sms_help.asp -->
-    <shortcode country="sg" pattern="7\\d{4}" premium="73800" standard="74688" />
+    <shortcode country="sg" pattern="7\\d{4}" premium="73800" standard="74688|70134" />
 
     <!-- Slovenia: 4 digits (premium=3xxx, 6xxx, 8xxx), plus EU: http://www.cmtelecom.com/premium-sms/slovenia -->
     <shortcode country="si" pattern="\\d{4}" premium="[368]\\d{3}" free="116\\d{3}" />
@@ -179,9 +194,15 @@
     <!-- Slovakia: 4 digits (premium), plus EU: http://www.cmtelecom.com/premium-sms/slovakia -->
     <shortcode country="sk" premium="\\d{4}" free="116\\d{3}" />
 
+    <!-- Thailand: 4186001 used by AIS_TH_DCB -->
+    <shortcode country="th" free="4186001" />
+
     <!-- Tajikistan: 4 digits, known premium codes listed -->
     <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
 
+    <!-- Turkey -->
+    <shortcode country="tr" free="7529|5528" />
+
     <!-- Ukraine: 4 digits, known premium codes listed -->
     <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
 
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/animation/AutoCancelTest.java b/core/tests/coretests/src/android/animation/AutoCancelTest.java
index 5810818..b1f88db 100644
--- a/core/tests/coretests/src/android/animation/AutoCancelTest.java
+++ b/core/tests/coretests/src/android/animation/AutoCancelTest.java
@@ -18,12 +18,10 @@
 import android.os.Handler;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
 
 import java.util.HashMap;
 import java.util.concurrent.TimeUnit;
 
-@Suppress  // Failing
 public class AutoCancelTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
 
     boolean mAnimX1Canceled = false;
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/android/text/StaticLayoutTextMeasuringTest.java b/core/tests/coretests/src/android/text/StaticLayoutTextMeasuringTest.java
new file mode 100644
index 0000000..2e0e6dc
--- /dev/null
+++ b/core/tests/coretests/src/android/text/StaticLayoutTextMeasuringTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.text;
+
+import android.text.Layout.Alignment;
+import junit.framework.TestCase;
+
+/**
+ * Tests for text measuring methods of StaticLayout.
+ */
+public class StaticLayoutTextMeasuringTest extends TestCase {
+    private static final float SPACE_MULTI = 1.0f;
+    private static final float SPACE_ADD = 0.0f;
+    private static final int DEFAULT_OUTER_WIDTH = 150;
+    private static final Alignment DEFAULT_ALIGN = Alignment.ALIGN_LEFT;
+
+    private TextPaint mDefaultPaint;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mDefaultPaint == null) {
+            mDefaultPaint = new TextPaint();
+        }
+    }
+
+    public void testGetPrimaryHorizontal_zwnbsp() {
+        // a, ZERO WIDTH NO-BREAK SPACE
+        String testString = "a\uFEFF";
+        StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
+                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+        assertEquals(0.0f, layout.getPrimaryHorizontal(0));
+        assertEquals(layout.getPrimaryHorizontal(2), layout.getPrimaryHorizontal(1));
+    }
+
+    public void testGetPrimaryHorizontal_devanagari() {
+        // DEVANAGARI LETTER KA, DEVANAGARI VOWEL SIGN AA
+        String testString = "\u0915\u093E";
+        StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
+                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+        assertEquals(0.0f, layout.getPrimaryHorizontal(0));
+        assertEquals(layout.getPrimaryHorizontal(2), layout.getPrimaryHorizontal(1));
+    }
+
+    public void testGetPrimaryHorizontal_flagEmoji() {
+        // REGIONAL INDICATOR SYMBOL LETTER U, REGIONAL INDICATOR SYMBOL LETTER S, REGIONAL
+        // INDICATOR SYMBOL LETTER Z
+        // First two code points (U and S) forms a US flag.
+        String testString = "\uD83C\uDDFA\uD83C\uDDF8\uD83C\uDDFF";
+        StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
+                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+        assertEquals(0.0f, layout.getPrimaryHorizontal(0));
+        assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(1));
+        assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(2));
+        assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(3));
+
+        assertTrue(layout.getPrimaryHorizontal(6) > layout.getPrimaryHorizontal(4));
+        assertEquals(layout.getPrimaryHorizontal(6), layout.getPrimaryHorizontal(5));
+    }
+}
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/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
index 48590c1..1966313 100644
--- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
@@ -22,6 +22,7 @@
 import android.view.ActionMode;
 import android.view.ActionMode.Callback;
 import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -32,6 +33,8 @@
 import android.view.WindowManager.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 
+import java.util.List;
+
 /**
  * Tests {@link PhoneWindow}'s {@link ActionMode} related methods.
  */
@@ -288,6 +291,9 @@
 
         @Override
         public void onActionModeFinished(ActionMode mode) {}
+
+        @Override
+        public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {}
     }
 
     private static final class MockActionModeCallback implements ActionMode.Callback {
diff --git a/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/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index b5b1a25..169ef0b 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -25,14 +25,14 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-import dalvik.system.VMRuntime;
-
 import java.io.OutputStream;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.IntBuffer;
 import java.nio.ShortBuffer;
 
+import libcore.util.NativeAllocationRegistry;
+
 public final class Bitmap implements Parcelable {
     private static final String TAG = "Bitmap";
 
@@ -44,6 +44,10 @@
      */
     public static final int DENSITY_NONE = 0;
 
+    // Estimated size of the Bitmap native allocation, not including
+    // pixel data.
+    private static final long NATIVE_ALLOCATION_SIZE = 32;
+
     /**
      * Backing buffer for the Bitmap.
      */
@@ -51,7 +55,6 @@
 
     // Convenience for JNI access
     private final long mNativePtr;
-    private final BitmapFinalizer mFinalizer;
 
     private final boolean mIsMutable;
 
@@ -125,9 +128,13 @@
         }
 
         mNativePtr = nativeBitmap;
-        mFinalizer = new BitmapFinalizer(nativeBitmap);
-        int nativeAllocationByteCount = (buffer == null ? getByteCount() : 0);
-        mFinalizer.setNativeAllocationByteCount(nativeAllocationByteCount);
+        long nativeSize = NATIVE_ALLOCATION_SIZE;
+        if (buffer == null) {
+            nativeSize += getByteCount();
+        }
+        NativeAllocationRegistry registry = new NativeAllocationRegistry(
+            nativeGetNativeFinalizer(), nativeSize);
+        registry.registerNativeAllocation(this, nativeBitmap);
     }
 
     /**
@@ -253,7 +260,7 @@
             throw new IllegalStateException("native-backed bitmaps may not be reconfigured");
         }
 
-        nativeReconfigure(mFinalizer.mNativeBitmap, width, height, config.nativeInt,
+        nativeReconfigure(mNativePtr, width, height, config.nativeInt,
                 mBuffer.length, mRequestPremultiplied);
         mWidth = width;
         mHeight = height;
@@ -330,8 +337,8 @@
      * there are no more references to this bitmap.
      */
     public void recycle() {
-        if (!mRecycled && mFinalizer.mNativeBitmap != 0) {
-            if (nativeRecycle(mFinalizer.mNativeBitmap)) {
+        if (!mRecycled && mNativePtr != 0) {
+            if (nativeRecycle(mNativePtr)) {
                 // return value indicates whether native pixel object was actually recycled.
                 // false indicates that it is still in use at the native level and these
                 // objects should not be collected now. They will be collected later when the
@@ -364,7 +371,7 @@
         if (mRecycled) {
             Log.w(TAG, "Called getGenerationId() on a recycle()'d bitmap! This is undefined behavior!");
         }
-        return nativeGenerationId(mFinalizer.mNativeBitmap);
+        return nativeGenerationId(mNativePtr);
     }
 
     /**
@@ -520,7 +527,7 @@
             throw new RuntimeException("Buffer not large enough for pixels");
         }
 
-        nativeCopyPixelsToBuffer(mFinalizer.mNativeBitmap, dst);
+        nativeCopyPixelsToBuffer(mNativePtr, dst);
 
         // now update the buffer's position
         int position = dst.position();
@@ -560,7 +567,7 @@
             throw new RuntimeException("Buffer not large enough for pixels");
         }
 
-        nativeCopyPixelsFromBuffer(mFinalizer.mNativeBitmap, src);
+        nativeCopyPixelsFromBuffer(mNativePtr, src);
 
         // now update the buffer's position
         int position = src.position();
@@ -582,7 +589,7 @@
      */
     public Bitmap copy(Config config, boolean isMutable) {
         checkRecycled("Can't copy a recycled bitmap");
-        Bitmap b = nativeCopy(mFinalizer.mNativeBitmap, config.nativeInt, isMutable);
+        Bitmap b = nativeCopy(mNativePtr, config.nativeInt, isMutable);
         if (b != null) {
             b.setPremultiplied(mRequestPremultiplied);
             b.mDensity = mDensity;
@@ -598,7 +605,7 @@
      */
     public Bitmap createAshmemBitmap() {
         checkRecycled("Can't copy a recycled bitmap");
-        Bitmap b = nativeCopyAshmem(mFinalizer.mNativeBitmap);
+        Bitmap b = nativeCopyAshmem(mNativePtr);
         if (b != null) {
             b.setPremultiplied(mRequestPremultiplied);
             b.mDensity = mDensity;
@@ -859,7 +866,7 @@
         }
         bm.setHasAlpha(hasAlpha);
         if (config == Config.ARGB_8888 && !hasAlpha) {
-            nativeErase(bm.mFinalizer.mNativeBitmap, 0xff000000);
+            nativeErase(bm.mNativePtr, 0xff000000);
         }
         // No need to initialize the bitmap to zeroes with other configs;
         // it is backed by a VM byte array which is by definition preinitialized
@@ -1049,7 +1056,7 @@
             throw new IllegalArgumentException("quality must be 0..100");
         }
         Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");
-        boolean result = nativeCompress(mFinalizer.mNativeBitmap, format.nativeInt,
+        boolean result = nativeCompress(mNativePtr, format.nativeInt,
                 quality, stream, new byte[WORKING_COMPRESS_STORAGE]);
         Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
         return result;
@@ -1093,7 +1100,7 @@
         if (mRecycled) {
             Log.w(TAG, "Called isPremultiplied() on a recycle()'d bitmap! This is undefined behavior!");
         }
-        return nativeIsPremultiplied(mFinalizer.mNativeBitmap);
+        return nativeIsPremultiplied(mNativePtr);
     }
 
     /**
@@ -1119,7 +1126,7 @@
     public final void setPremultiplied(boolean premultiplied) {
         checkRecycled("setPremultiplied called on a recycled bitmap");
         mRequestPremultiplied = premultiplied;
-        nativeSetPremultiplied(mFinalizer.mNativeBitmap, premultiplied);
+        nativeSetPremultiplied(mNativePtr, premultiplied);
     }
 
     /** Returns the bitmap's width */
@@ -1220,7 +1227,7 @@
         if (mRecycled) {
             Log.w(TAG, "Called getRowBytes() on a recycle()'d bitmap! This is undefined behavior!");
         }
-        return nativeRowBytes(mFinalizer.mNativeBitmap);
+        return nativeRowBytes(mNativePtr);
     }
 
     /**
@@ -1266,7 +1273,7 @@
         if (mRecycled) {
             Log.w(TAG, "Called getConfig() on a recycle()'d bitmap! This is undefined behavior!");
         }
-        return Config.nativeToConfig(nativeConfig(mFinalizer.mNativeBitmap));
+        return Config.nativeToConfig(nativeConfig(mNativePtr));
     }
 
     /** Returns true if the bitmap's config supports per-pixel alpha, and
@@ -1281,7 +1288,7 @@
         if (mRecycled) {
             Log.w(TAG, "Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!");
         }
-        return nativeHasAlpha(mFinalizer.mNativeBitmap);
+        return nativeHasAlpha(mNativePtr);
     }
 
     /**
@@ -1296,7 +1303,7 @@
      */
     public void setHasAlpha(boolean hasAlpha) {
         checkRecycled("setHasAlpha called on a recycled bitmap");
-        nativeSetHasAlpha(mFinalizer.mNativeBitmap, hasAlpha, mRequestPremultiplied);
+        nativeSetHasAlpha(mNativePtr, hasAlpha, mRequestPremultiplied);
     }
 
     /**
@@ -1320,7 +1327,7 @@
         if (mRecycled) {
             Log.w(TAG, "Called hasMipMap() on a recycle()'d bitmap! This is undefined behavior!");
         }
-        return nativeHasMipMap(mFinalizer.mNativeBitmap);
+        return nativeHasMipMap(mNativePtr);
     }
 
     /**
@@ -1345,7 +1352,7 @@
      */
     public final void setHasMipMap(boolean hasMipMap) {
         checkRecycled("setHasMipMap called on a recycled bitmap");
-        nativeSetHasMipMap(mFinalizer.mNativeBitmap, hasMipMap);
+        nativeSetHasMipMap(mNativePtr, hasMipMap);
     }
 
     /**
@@ -1358,7 +1365,7 @@
         if (!isMutable()) {
             throw new IllegalStateException("cannot erase immutable bitmaps");
         }
-        nativeErase(mFinalizer.mNativeBitmap, c);
+        nativeErase(mNativePtr, c);
     }
 
     /**
@@ -1375,7 +1382,7 @@
     public int getPixel(int x, int y) {
         checkRecycled("Can't call getPixel() on a recycled bitmap");
         checkPixelAccess(x, y);
-        return nativeGetPixel(mFinalizer.mNativeBitmap, x, y);
+        return nativeGetPixel(mNativePtr, x, y);
     }
 
     /**
@@ -1408,7 +1415,7 @@
             return; // nothing to do
         }
         checkPixelsAccess(x, y, width, height, offset, stride, pixels);
-        nativeGetPixels(mFinalizer.mNativeBitmap, pixels, offset, stride,
+        nativeGetPixels(mNativePtr, pixels, offset, stride,
                         x, y, width, height);
     }
 
@@ -1489,7 +1496,7 @@
             throw new IllegalStateException();
         }
         checkPixelAccess(x, y);
-        nativeSetPixel(mFinalizer.mNativeBitmap, x, y, color);
+        nativeSetPixel(mNativePtr, x, y, color);
     }
 
     /**
@@ -1525,7 +1532,7 @@
             return; // nothing to do
         }
         checkPixelsAccess(x, y, width, height, offset, stride, pixels);
-        nativeSetPixels(mFinalizer.mNativeBitmap, pixels, offset, stride,
+        nativeSetPixels(mNativePtr, pixels, offset, stride,
                         x, y, width, height);
     }
 
@@ -1563,7 +1570,7 @@
      */
     public void writeToParcel(Parcel p, int flags) {
         checkRecycled("Can't parcel a recycled bitmap");
-        if (!nativeWriteToParcel(mFinalizer.mNativeBitmap, mIsMutable, mDensity, p)) {
+        if (!nativeWriteToParcel(mNativePtr, mIsMutable, mDensity, p)) {
             throw new RuntimeException("native writeToParcel failed");
         }
     }
@@ -1609,7 +1616,7 @@
     public Bitmap extractAlpha(Paint paint, int[] offsetXY) {
         checkRecycled("Can't extractAlpha on a recycled bitmap");
         long nativePaint = paint != null ? paint.getNativeInstance() : 0;
-        Bitmap bm = nativeExtractAlpha(mFinalizer.mNativeBitmap, nativePaint, offsetXY);
+        Bitmap bm = nativeExtractAlpha(mNativePtr, nativePaint, offsetXY);
         if (bm == null) {
             throw new RuntimeException("Failed to extractAlpha on Bitmap");
         }
@@ -1629,7 +1636,7 @@
         if (other.isRecycled()) {
             throw new IllegalArgumentException("Can't compare to a recycled bitmap!");
         }
-        return nativeSameAs(mFinalizer.mNativeBitmap, other.mFinalizer.mNativeBitmap);
+        return nativeSameAs(mNativePtr, other.mNativePtr);
     }
 
     /**
@@ -1660,41 +1667,6 @@
         return nativeRefPixelRef(mNativePtr);
     }
 
-    private static class BitmapFinalizer {
-        private long mNativeBitmap;
-
-        // Native memory allocated for the duration of the Bitmap,
-        // if pixel data allocated into native memory, instead of java byte[]
-        private int mNativeAllocationByteCount;
-
-        BitmapFinalizer(long nativeBitmap) {
-            mNativeBitmap = nativeBitmap;
-        }
-
-        public void setNativeAllocationByteCount(int nativeByteCount) {
-            if (mNativeAllocationByteCount != 0) {
-                VMRuntime.getRuntime().registerNativeFree(mNativeAllocationByteCount);
-            }
-            mNativeAllocationByteCount = nativeByteCount;
-            if (mNativeAllocationByteCount != 0) {
-                VMRuntime.getRuntime().registerNativeAllocation(mNativeAllocationByteCount);
-            }
-        }
-
-        @Override
-        public void finalize() {
-            try {
-                super.finalize();
-            } catch (Throwable t) {
-                // Ignore
-            } finally {
-                setNativeAllocationByteCount(0);
-                nativeDestructor(mNativeBitmap);
-                mNativeBitmap = 0;
-            }
-        }
-    }
-
     //////////// native methods
 
     private static native Bitmap nativeCreate(int[] colors, int offset,
@@ -1703,7 +1675,7 @@
     private static native Bitmap nativeCopy(long nativeSrcBitmap, int nativeConfig,
                                             boolean isMutable);
     private static native Bitmap nativeCopyAshmem(long nativeSrcBitmap);
-    private static native void nativeDestructor(long nativeBitmap);
+    private static native long nativeGetNativeFinalizer();
     private static native boolean nativeRecycle(long nativeBitmap);
     private static native void nativeReconfigure(long nativeBitmap, int width, int height,
                                                  int config, int allocSize,
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 1cc5346..d4f745d 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -31,6 +31,8 @@
 
 import javax.microedition.khronos.opengles.GL;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * The Canvas class holds the "draw" calls. To draw something, you need
  * 4 basic components: A Bitmap to hold the pixels, a Canvas to host
@@ -50,7 +52,7 @@
 
     /**
      * Should only be assigned in constructors (or setBitmap if software canvas),
-     * freed in finalizer.
+     * freed by NativeAllocation.
      * @hide
      */
     protected long mNativeCanvasWrapper;
@@ -85,32 +87,15 @@
     // (see SkCanvas.cpp, SkDraw.cpp)
     private static final int MAXMIMUM_BITMAP_SIZE = 32766;
 
+    // The approximate size of the native allocation associated with
+    // a Canvas object.
+    private static final long NATIVE_ALLOCATION_SIZE = 525;
+
+    private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+        getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
+
     // This field is used to finalize the native Canvas properly
-    private final CanvasFinalizer mFinalizer;
-
-    private static final class CanvasFinalizer {
-        private long mNativeCanvasWrapper;
-
-        public CanvasFinalizer(long nativeCanvas) {
-            mNativeCanvasWrapper = nativeCanvas;
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                dispose();
-            } finally {
-                super.finalize();
-            }
-        }
-
-        public void dispose() {
-            if (mNativeCanvasWrapper != 0) {
-                finalizer(mNativeCanvasWrapper);
-                mNativeCanvasWrapper = 0;
-            }
-        }
-    }
+    private Runnable mFinalizer;
 
     /**
      * Construct an empty raster canvas. Use setBitmap() to specify a bitmap to
@@ -122,7 +107,7 @@
         if (!isHardwareAccelerated()) {
             // 0 means no native bitmap
             mNativeCanvasWrapper = initRaster(null);
-            mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
+            mFinalizer = sRegistry.registerNativeAllocation(this, mNativeCanvasWrapper);
         } else {
             mFinalizer = null;
         }
@@ -143,7 +128,7 @@
         }
         throwIfCannotDraw(bitmap);
         mNativeCanvasWrapper = initRaster(bitmap);
-        mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
+        mFinalizer = sRegistry.registerNativeAllocation(this, mNativeCanvasWrapper);
         mBitmap = bitmap;
         mDensity = bitmap.mDensity;
     }
@@ -154,7 +139,7 @@
             throw new IllegalStateException();
         }
         mNativeCanvasWrapper = nativeCanvas;
-        mFinalizer = new CanvasFinalizer(mNativeCanvasWrapper);
+        mFinalizer = sRegistry.registerNativeAllocation(this, mNativeCanvasWrapper);
         mDensity = Bitmap.getDefaultDensity();
     }
 
@@ -1980,7 +1965,11 @@
      * @hide
      */
     public void release() {
-        mFinalizer.dispose();
+        mNativeCanvasWrapper = 0;
+        if (mFinalizer != null) {
+            mFinalizer.run();
+            mFinalizer = null;
+        }
     }
 
     /**
@@ -2148,5 +2137,5 @@
                                                      float hOffset,
                                                      float vOffset,
                                                      int flags, long nativePaint, long nativeTypeface);
-    private static native void finalizer(long nativeCanvas);
+    private static native long getNativeFinalizer();
 }
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 90522f7..dfb8bb8 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -30,6 +30,8 @@
 import java.util.HashMap;
 import java.util.Locale;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * The Paint class holds the style and color information about how to draw
  * geometries, text and bitmaps.
@@ -39,6 +41,12 @@
     private long mNativePaint;
     private long mNativeShader = 0;
 
+    // The approximate size of a native paint object.
+    private static final long NATIVE_PAINT_SIZE = 98;
+
+    private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+        nGetNativeFinalizer(), NATIVE_PAINT_SIZE);
+
     /**
      * @hide
      */
@@ -444,6 +452,7 @@
      */
     public Paint(int flags) {
         mNativePaint = nInit();
+        sRegistry.registerNativeAllocation(this, mNativePaint);
         setFlags(flags | HIDDEN_DEFAULT_PAINT_FLAGS);
         // TODO: Turning off hinting has undesirable side effects, we need to
         //       revisit hinting once we add support for subpixel positioning
@@ -462,12 +471,12 @@
      */
     public Paint(Paint paint) {
         mNativePaint = nInitWithPaint(paint.getNativeInstance());
+        sRegistry.registerNativeAllocation(this, mNativePaint);
         setClassVariablesFrom(paint);
     }
 
     /** Restores the paint to its default settings. */
     public void reset() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nReset(mNativePaint);
         setFlags(HIDDEN_DEFAULT_PAINT_FLAGS);
 
@@ -502,8 +511,6 @@
      * methods on this.
      */
     public void set(Paint src) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
-        if (src.mNativePaint == 0) throw new NullPointerException("Source is already finalized!");
         if (this != src) {
             // copy over the native settings
             nSet(mNativePaint, src.mNativePaint);
@@ -554,7 +561,6 @@
      * @hide
      */
     public long getNativeInstance() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         long newNativeShader = mShader == null ? 0 : mShader.getNativeInstance();
         if (newNativeShader != mNativeShader) {
             mNativeShader = newNativeShader;
@@ -592,7 +598,6 @@
      * @return the paint's flags (see enums ending in _Flag for bit masks)
      */
     public int getFlags() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetFlags(mNativePaint);
     }
 
@@ -604,7 +609,6 @@
      * @param flags The new flag bits for the paint
      */
     public void setFlags(int flags) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetFlags(mNativePaint, flags);
     }
 
@@ -615,7 +619,6 @@
      * {@link #HINTING_OFF} or {@link #HINTING_ON}.
      */
     public int getHinting() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetHinting(mNativePaint);
     }
 
@@ -626,7 +629,6 @@
      * {@link #HINTING_OFF} or {@link #HINTING_ON}.
      */
     public void setHinting(int mode) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetHinting(mNativePaint, mode);
     }
 
@@ -653,7 +655,6 @@
      * @param aa true to set the antialias bit in the flags, false to clear it
      */
     public void setAntiAlias(boolean aa) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetAntiAlias(mNativePaint, aa);
     }
 
@@ -684,7 +685,6 @@
      * @param dither true to set the dithering bit in flags, false to clear it
      */
     public void setDither(boolean dither) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetDither(mNativePaint, dither);
     }
 
@@ -706,7 +706,6 @@
      *                   false to clear it.
      */
     public void setLinearText(boolean linearText) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetLinearText(mNativePaint, linearText);
     }
 
@@ -728,7 +727,6 @@
      *                     flags, false to clear it.
      */
     public void setSubpixelText(boolean subpixelText) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetSubpixelText(mNativePaint, subpixelText);
     }
 
@@ -750,7 +748,6 @@
      *                      flags, false to clear it.
      */
     public void setUnderlineText(boolean underlineText) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetUnderlineText(mNativePaint, underlineText);
     }
 
@@ -772,7 +769,6 @@
      *                       flags, false to clear it.
      */
     public void setStrikeThruText(boolean strikeThruText) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetStrikeThruText(mNativePaint, strikeThruText);
     }
 
@@ -794,7 +790,6 @@
      *                     flags, false to clear it.
      */
     public void setFakeBoldText(boolean fakeBoldText) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetFakeBoldText(mNativePaint, fakeBoldText);
     }
 
@@ -822,7 +817,6 @@
      *               flags, false to clear it.
      */
     public void setFilterBitmap(boolean filter) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetFilterBitmap(mNativePaint, filter);
     }
 
@@ -836,7 +830,6 @@
      * @return the paint's style setting (Fill, Stroke, StrokeAndFill)
      */
     public Style getStyle() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return sStyleArray[nGetStyle(mNativePaint)];
     }
 
@@ -848,7 +841,6 @@
      * @param style The new style to set in the paint
      */
     public void setStyle(Style style) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetStyle(mNativePaint, style.nativeInt);
     }
 
@@ -862,7 +854,6 @@
      */
     @ColorInt
     public int getColor() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetColor(mNativePaint);
     }
 
@@ -877,7 +868,6 @@
      * @param color The new color (including alpha) to set in the paint.
      */
     public void setColor(@ColorInt int color) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetColor(mNativePaint, color);
     }
 
@@ -891,7 +881,6 @@
      * @return the alpha component of the paint's color.
      */
     public int getAlpha() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetAlpha(mNativePaint);
     }
 
@@ -905,7 +894,6 @@
      * @param a set the alpha component [0..255] of the paint's color.
      */
     public void setAlpha(int a) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetAlpha(mNativePaint, a);
     }
 
@@ -933,7 +921,6 @@
      *         Stroke or StrokeAndFill.
      */
     public float getStrokeWidth() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetStrokeWidth(mNativePaint);
     }
 
@@ -948,7 +935,6 @@
      *              style is Stroke or StrokeAndFill.
      */
     public void setStrokeWidth(float width) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetStrokeWidth(mNativePaint, width);
     }
 
@@ -962,7 +948,6 @@
      *         Stroke or StrokeAndFill.
      */
     public float getStrokeMiter() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetStrokeMiter(mNativePaint);
     }
 
@@ -976,7 +961,6 @@
      *              style is Stroke or StrokeAndFill.
      */
     public void setStrokeMiter(float miter) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetStrokeMiter(mNativePaint, miter);
     }
 
@@ -990,7 +974,6 @@
      *         style is Stroke or StrokeAndFill.
      */
     public Cap getStrokeCap() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return sCapArray[nGetStrokeCap(mNativePaint)];
     }
 
@@ -1001,7 +984,6 @@
      *            style is Stroke or StrokeAndFill.
      */
     public void setStrokeCap(Cap cap) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetStrokeCap(mNativePaint, cap.nativeInt);
     }
 
@@ -1011,7 +993,6 @@
      * @return the paint's Join.
      */
     public Join getStrokeJoin() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return sJoinArray[nGetStrokeJoin(mNativePaint)];
     }
 
@@ -1022,7 +1003,6 @@
      *             Stroke or StrokeAndFill.
      */
     public void setStrokeJoin(Join join) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetStrokeJoin(mNativePaint, join.nativeInt);
     }
 
@@ -1038,7 +1018,6 @@
      *                 drawn with a hairline (width == 0)
      */
     public boolean getFillPath(Path src, Path dst) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetFillPath(mNativePaint, src.ni(), dst.ni());
     }
 
@@ -1061,6 +1040,11 @@
      * @return       shader
      */
     public Shader setShader(Shader shader) {
+        // If mShader changes, cached value of native shader aren't valid, since
+        // old shader's pointer may be reused by another shader allocation later
+        if (mShader != shader) {
+            mNativeShader = -1;
+        }
         // Defer setting the shader natively until getNativeInstance() is called
         mShader = shader;
         return shader;
@@ -1082,7 +1066,6 @@
      * @return       filter
      */
     public ColorFilter setColorFilter(ColorFilter filter) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         long filterNative = 0;
         if (filter != null)
             filterNative = filter.native_instance;
@@ -1110,7 +1093,6 @@
      * @return         xfermode
      */
     public Xfermode setXfermode(Xfermode xfermode) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         long xfermodeNative = 0;
         if (xfermode != null)
             xfermodeNative = xfermode.native_instance;
@@ -1138,7 +1120,6 @@
      * @return       effect
      */
     public PathEffect setPathEffect(PathEffect effect) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         long effectNative = 0;
         if (effect != null) {
             effectNative = effect.native_instance;
@@ -1168,7 +1149,6 @@
      * @return           maskfilter
      */
     public MaskFilter setMaskFilter(MaskFilter maskfilter) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         long maskfilterNative = 0;
         if (maskfilter != null) {
             maskfilterNative = maskfilter.native_instance;
@@ -1200,7 +1180,6 @@
      * @return         typeface
      */
     public Typeface setTypeface(Typeface typeface) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         long typefaceNative = 0;
         if (typeface != null) {
             typefaceNative = typeface.native_instance;
@@ -1239,7 +1218,6 @@
      */
     @Deprecated
     public Rasterizer setRasterizer(Rasterizer rasterizer) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         long rasterizerNative = 0;
         if (rasterizer != null) {
             rasterizerNative = rasterizer.native_instance;
@@ -1262,7 +1240,6 @@
      * opaque, or the alpha from the shadow color if not.
      */
     public void setShadowLayer(float radius, float dx, float dy, int shadowColor) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
       nSetShadowLayer(mNativePaint, radius, dx, dy, shadowColor);
     }
 
@@ -1280,7 +1257,6 @@
      * @hide
      */
     public boolean hasShadowLayer() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nHasShadowLayer(mNativePaint);
     }
 
@@ -1293,7 +1269,6 @@
      * @return the paint's Align value for drawing text.
      */
     public Align getTextAlign() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return sAlignArray[nGetTextAlign(mNativePaint)];
     }
 
@@ -1306,7 +1281,6 @@
      * @param align set the paint's Align value for drawing text.
      */
     public void setTextAlign(Align align) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetTextAlign(mNativePaint, align.nativeInt);
     }
 
@@ -1340,7 +1314,6 @@
      * @param locale the paint's locale value for drawing text, must not be null.
      */
     public void setTextLocale(@NonNull Locale locale) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (locale == null) {
             throw new IllegalArgumentException("locale cannot be null");
         }
@@ -1379,7 +1352,6 @@
      * @param locales the paint's locale list for drawing text, must not be null or empty.
      */
     public void setTextLocales(@NonNull @Size(min=1) LocaleList locales) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (locales == null || locales.isEmpty()) {
             throw new IllegalArgumentException("locales cannot be null or empty");
         }
@@ -1408,7 +1380,6 @@
      * @return true if elegant metrics are enabled for text drawing.
      */
     public boolean isElegantTextHeight() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nIsElegantTextHeight(mNativePaint);
     }
 
@@ -1422,7 +1393,6 @@
      * @param elegant set the paint's elegant metrics flag for drawing text.
      */
     public void setElegantTextHeight(boolean elegant) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetElegantTextHeight(mNativePaint, elegant);
     }
 
@@ -1434,7 +1404,6 @@
      * @return the paint's text size.
      */
     public float getTextSize() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetTextSize(mNativePaint);
     }
 
@@ -1446,7 +1415,6 @@
      * @param textSize set the paint's text size.
      */
     public void setTextSize(float textSize) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetTextSize(mNativePaint, textSize);
     }
 
@@ -1459,7 +1427,6 @@
      * @return the paint's scale factor in X for drawing/measuring text
      */
     public float getTextScaleX() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetTextScaleX(mNativePaint);
     }
 
@@ -1473,7 +1440,6 @@
      * @param scaleX set the paint's scale in X for drawing/measuring text.
      */
     public void setTextScaleX(float scaleX) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetTextScaleX(mNativePaint, scaleX);
     }
 
@@ -1486,7 +1452,6 @@
      * @return         the paint's skew factor in X for drawing text.
      */
     public float getTextSkewX() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetTextSkewX(mNativePaint);
     }
 
@@ -1499,7 +1464,6 @@
      * @param skewX set the paint's skew factor in X for drawing text.
      */
     public void setTextSkewX(float skewX) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetTextSkewX(mNativePaint, skewX);
     }
 
@@ -1512,7 +1476,6 @@
      * @return         the paint's letter-spacing for drawing text.
      */
     public float getLetterSpacing() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetLetterSpacing(mNativePaint);
     }
 
@@ -1524,7 +1487,6 @@
      * @param letterSpacing set the paint's letter-spacing for drawing text.
      */
     public void setLetterSpacing(float letterSpacing) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetLetterSpacing(mNativePaint, letterSpacing);
     }
 
@@ -1546,7 +1508,6 @@
      * @param settings the font feature settings string to use, may be null.
      */
     public void setFontFeatureSettings(String settings) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (settings != null && settings.equals("")) {
             settings = null;
         }
@@ -1566,7 +1527,6 @@
      * @hide
      */
     public int getHyphenEdit() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetHyphenEdit(mNativePaint);
     }
 
@@ -1579,7 +1539,6 @@
      * @hide
      */
     public void setHyphenEdit(int hyphen) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         nSetHyphenEdit(mNativePaint, hyphen);
     }
 
@@ -1591,7 +1550,6 @@
      *         current typeface and text size.
      */
     public float ascent() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nAscent(mNativePaint, mNativeTypeface);
     }
 
@@ -1605,7 +1563,6 @@
      *         the current typeface and text size.
      */
     public float descent() {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nDescent(mNativePaint, mNativeTypeface);
     }
 
@@ -1652,7 +1609,6 @@
      * @return the font's recommended interline spacing.
      */
     public float getFontMetrics(FontMetrics metrics) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetFontMetrics(mNativePaint, mNativeTypeface, metrics);
     }
 
@@ -1698,7 +1654,6 @@
      * @return the font's interline spacing.
      */
     public int getFontMetricsInt(FontMetricsInt fmi) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nGetFontMetricsInt(mNativePaint, mNativeTypeface, fmi);
     }
 
@@ -1731,7 +1686,6 @@
      * @return      The width of the text
      */
     public float measureText(char[] text, int index, int count) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -1764,7 +1718,6 @@
      * @return      The width of the text
      */
     public float measureText(String text, int start, int end) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -1794,7 +1747,6 @@
      * @return      The width of the text
      */
     public float measureText(String text) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -1855,7 +1807,6 @@
      */
     public int breakText(char[] text, int index, int count,
                                 float maxWidth, float[] measuredWidth) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -1903,7 +1854,6 @@
     public int breakText(CharSequence text, int start, int end,
                          boolean measureForwards,
                          float maxWidth, float[] measuredWidth) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -1952,7 +1902,6 @@
      */
     public int breakText(String text, boolean measureForwards,
                                 float maxWidth, float[] measuredWidth) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -1990,7 +1939,6 @@
      */
     public int getTextWidths(char[] text, int index, int count,
                              float[] widths) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2074,7 +2022,6 @@
      * @return       the number of code units in the specified text.
      */
     public int getTextWidths(String text, int start, int end, float[] widths) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2128,7 +2075,6 @@
             int contextIndex, int contextCount, boolean isRtl, float[] advances,
             int advancesIndex) {
 
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (chars == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2175,7 +2121,6 @@
     public float getTextRunAdvances(CharSequence text, int start, int end,
             int contextStart, int contextEnd, boolean isRtl, float[] advances,
             int advancesIndex) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2257,7 +2202,6 @@
      */
     public float getTextRunAdvances(String text, int start, int end, int contextStart,
             int contextEnd, boolean isRtl, float[] advances, int advancesIndex) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2322,7 +2266,6 @@
      */
     public int getTextRunCursor(char[] text, int contextStart, int contextLength,
             int dir, int offset, int cursorOpt) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         int contextEnd = contextStart + contextLength;
         if (((contextStart | contextEnd | offset | (contextEnd - contextStart)
                 | (offset - contextStart) | (contextEnd - offset)
@@ -2410,7 +2353,6 @@
      */
     public int getTextRunCursor(String text, int contextStart, int contextEnd,
             int dir, int offset, int cursorOpt) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (((contextStart | contextEnd | offset | (contextEnd - contextStart)
                 | (offset - contextStart) | (contextEnd - offset)
                 | (text.length() - contextEnd) | cursorOpt) < 0)
@@ -2437,7 +2379,6 @@
      */
     public void getTextPath(char[] text, int index, int count,
                             float x, float y, Path path) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if ((index | count) < 0 || index + count > text.length) {
             throw new ArrayIndexOutOfBoundsException();
         }
@@ -2460,7 +2401,6 @@
      */
     public void getTextPath(String text, int start, int end,
                             float x, float y, Path path) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if ((start | end | (end - start) | (text.length() - end)) < 0) {
             throw new IndexOutOfBoundsException();
         }
@@ -2479,7 +2419,6 @@
      *               allocated by the caller.
      */
     public void getTextBounds(String text, int start, int end, Rect bounds) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if ((start | end | (end - start) | (text.length() - end)) < 0) {
             throw new IndexOutOfBoundsException();
         }
@@ -2500,7 +2439,6 @@
      *               allocated by the caller.
      */
     public void getTextBounds(char[] text, int index, int count, Rect bounds) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if ((index | count) < 0 || index + count > text.length) {
             throw new ArrayIndexOutOfBoundsException();
         }
@@ -2528,7 +2466,6 @@
      * @return true if the typeface has a glyph for the string
      */
     public boolean hasGlyph(String string) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         return nHasGlyph(mNativePaint, mNativeTypeface, mBidiFlags, string);
     }
 
@@ -2570,7 +2507,6 @@
      */
     public float getRunAdvance(char[] text, int start, int end, int contextStart, int contextEnd,
             boolean isRtl, int offset) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2601,7 +2537,6 @@
      */
     public float getRunAdvance(CharSequence text, int start, int end, int contextStart,
             int contextEnd, boolean isRtl, int offset) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2652,7 +2587,6 @@
      */
     public int getOffsetForAdvance(char[] text, int start, int end, int contextStart,
             int contextEnd, boolean isRtl, float advance) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2680,7 +2614,6 @@
      */
     public int getOffsetForAdvance(CharSequence text, int start, int end, int contextStart,
             int contextEnd, boolean isRtl, float advance) {
-        if (mNativePaint == 0) throw new NullPointerException("Already finalized!");
         if (text == null) {
             throw new IllegalArgumentException("text cannot be null");
         }
@@ -2698,18 +2631,6 @@
         return result;
     }
 
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mNativePaint != 0) {
-                nFinalizer(mNativePaint);
-                mNativePaint = 0;
-            }
-        } finally {
-            super.finalize();
-        }
-    }
-
     private static native long nInit();
     private static native long nInitWithPaint(long paint);
     private static native void nReset(long paintPtr);
@@ -2765,7 +2686,7 @@
                                 String text, int start, int end, int bidiFlags, Rect bounds);
     private static native void nGetCharArrayBounds(long nativePaint, long typefacePtr,
                                 char[] text, int index, int count, int bidiFlags, Rect bounds);
-    private static native void nFinalizer(long nativePaint);
+    private static native long nGetNativeFinalizer();
 
     private static native void nSetShadowLayer(long paintPtr,
             float radius, float dx, float dy, int color);
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 78424e3..c0dfe77 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -204,11 +204,13 @@
 
     /**
      * Sets the X position around which the drawable is rotated.
+     * <p>
+     * If the X pivot is relative (as specified by
+     * {@link #setPivotXRelative(boolean)}), then the position represents a
+     * fraction of the drawable width. Otherwise, the position represents an
+     * absolute value in pixels.
      *
-     * @param pivotX X position around which to rotate. If the X pivot is
-     *            relative, the position represents a fraction of the drawable
-     *            width. Otherwise, the position represents an absolute value in
-     *            pixels.
+     * @param pivotX X position around which to rotate
      * @see #setPivotXRelative(boolean)
      * @attr ref android.R.styleable#RotateDrawable_pivotX
      */
@@ -254,11 +256,13 @@
 
     /**
      * Sets the Y position around which the drawable is rotated.
+     * <p>
+     * If the Y pivot is relative (as specified by
+     * {@link #setPivotYRelative(boolean)}), then the position represents a
+     * fraction of the drawable height. Otherwise, the position represents an
+     * absolute value in pixels.
      *
-     * @param pivotY Y position around which to rotate. If the Y pivot is
-     *            relative, the position represents a fraction of the drawable
-     *            height. Otherwise, the position represents an absolute value
-     *            in pixels.
+     * @param pivotY Y position around which to rotate
      * @see #getPivotY()
      * @attr ref android.R.styleable#RotateDrawable_pivotY
      */
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 86368f0..8ba6318 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -53,6 +53,7 @@
     FrameInfoVisualizer.cpp \
     GammaFontRenderer.cpp \
     GlopBuilder.cpp \
+    GpuMemoryTracker.cpp \
     GradientCache.cpp \
     Image.cpp \
     Interpolator.cpp \
@@ -225,9 +226,11 @@
     $(hwui_test_common_src_files) \
     tests/unit/CanvasStateTests.cpp \
     tests/unit/ClipAreaTests.cpp \
+    tests/unit/CrashHandlerInjector.cpp \
     tests/unit/DamageAccumulatorTests.cpp \
     tests/unit/DeviceInfoTests.cpp \
     tests/unit/FatVectorTests.cpp \
+    tests/unit/GpuMemoryTrackerTests.cpp \
     tests/unit/LayerUpdateQueueTests.cpp \
     tests/unit/LinearAllocatorTests.cpp \
     tests/unit/VectorDrawableTests.cpp \
@@ -238,6 +241,7 @@
     LOCAL_SRC_FILES += \
         tests/unit/BakedOpStateTests.cpp \
         tests/unit/FrameBuilderTests.cpp \
+        tests/unit/LeakCheckTests.cpp \
         tests/unit/RecordingCanvasTests.cpp
 endif
 
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index 41411a9..6afff1b 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -39,40 +39,22 @@
         if (!mTexture) {
             Caches& caches = Caches::getInstance();
             mTexture = new Texture(caches);
-            mTexture->width = buffer->getWidth();
-            mTexture->height = buffer->getHeight();
+            mTexture->wrap(mImage->getTexture(),
+                    buffer->getWidth(), buffer->getHeight(), GL_RGBA);
             createEntries(caches, map, count);
         }
     } else {
         ALOGW("Could not create atlas image");
-        delete mImage;
-        mImage = nullptr;
+        terminate();
     }
-
-    updateTextureId();
 }
 
 void AssetAtlas::terminate() {
-    if (mImage) {
-        delete mImage;
-        mImage = nullptr;
-        updateTextureId();
-    }
-}
-
-
-void AssetAtlas::updateTextureId() {
-    mTexture->id = mImage ? mImage->getTexture() : 0;
-    if (mTexture->id) {
-        // Texture ID changed, force-set to defaults to sync the wrapper & GL
-        // state objects
-        mTexture->setWrap(GL_CLAMP_TO_EDGE, false, true);
-        mTexture->setFilter(GL_NEAREST, false, true);
-    }
-    for (size_t i = 0; i < mEntries.size(); i++) {
-        AssetAtlas::Entry* entry = mEntries.valueAt(i);
-        entry->texture->id = mTexture->id;
-    }
+    delete mImage;
+    mImage = nullptr;
+    delete mTexture;
+    mTexture = nullptr;
+    mEntries.clear();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -80,13 +62,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 AssetAtlas::Entry* AssetAtlas::getEntry(const SkPixelRef* pixelRef) const {
-    ssize_t index = mEntries.indexOfKey(pixelRef);
-    return index >= 0 ? mEntries.valueAt(index) : nullptr;
+    auto result = mEntries.find(pixelRef);
+    return result != mEntries.end() ? result->second.get() : nullptr;
 }
 
 Texture* AssetAtlas::getEntryTexture(const SkPixelRef* pixelRef) const {
-    ssize_t index = mEntries.indexOfKey(pixelRef);
-    return index >= 0 ? mEntries.valueAt(index)->texture : nullptr;
+    auto result = mEntries.find(pixelRef);
+    return result != mEntries.end() ? result->second->texture : nullptr;
 }
 
 /**
@@ -94,7 +76,8 @@
  * instead of applying the changes to the virtual textures.
  */
 struct DelegateTexture: public Texture {
-    DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { }
+    DelegateTexture(Caches& caches, Texture* delegate)
+            : Texture(caches), mDelegate(delegate) { }
 
     virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
             bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override {
@@ -111,8 +94,8 @@
 }; // struct DelegateTexture
 
 void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {
-    const float width = float(mTexture->width);
-    const float height = float(mTexture->height);
+    const float width = float(mTexture->width());
+    const float height = float(mTexture->height());
 
     for (int i = 0; i < count; ) {
         SkPixelRef* pixelRef = reinterpret_cast<SkPixelRef*>(map[i++]);
@@ -133,13 +116,13 @@
 
         Texture* texture = new DelegateTexture(caches, mTexture);
         texture->blend = !SkAlphaTypeIsOpaque(pixelRef->info().alphaType());
-        texture->width = pixelRef->info().width();
-        texture->height = pixelRef->info().height();
+        texture->wrap(mTexture->id(), pixelRef->info().width(),
+                pixelRef->info().height(), mTexture->format());
 
-        Entry* entry = new Entry(pixelRef, texture, mapper, *this);
+        std::unique_ptr<Entry> entry(new Entry(pixelRef, texture, mapper, *this));
         texture->uvMapper = &entry->uvMapper;
 
-        mEntries.add(entry->pixelRef, entry);
+        mEntries.emplace(entry->pixelRef, std::move(entry));
     }
 }
 
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index a037725..75400ff 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -17,19 +17,17 @@
 #ifndef ANDROID_HWUI_ASSET_ATLAS_H
 #define ANDROID_HWUI_ASSET_ATLAS_H
 
-#include <GLES2/gl2.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include <utils/KeyedVector.h>
-
-#include <cutils/compiler.h>
-
-#include <SkBitmap.h>
-
 #include "Texture.h"
 #include "UvMapper.h"
 
+#include <cutils/compiler.h>
+#include <GLES2/gl2.h>
+#include <ui/GraphicBuffer.h>
+#include <SkBitmap.h>
+
+#include <memory>
+#include <unordered_map>
+
 namespace android {
 namespace uirenderer {
 
@@ -71,6 +69,10 @@
             return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
         }
 
+        ~Entry() {
+            delete texture;
+        }
+
     private:
         /**
          * The pixel ref that generated this atlas entry.
@@ -90,10 +92,6 @@
                 , atlas(atlas) {
         }
 
-        ~Entry() {
-            delete texture;
-        }
-
         friend class AssetAtlas;
     };
 
@@ -127,7 +125,7 @@
      * Can return 0 if the atlas is not initialized.
      */
     uint32_t getWidth() const {
-        return mTexture ? mTexture->width : 0;
+        return mTexture ? mTexture->width() : 0;
     }
 
     /**
@@ -135,7 +133,7 @@
      * Can return 0 if the atlas is not initialized.
      */
     uint32_t getHeight() const {
-        return mTexture ? mTexture->height : 0;
+        return mTexture ? mTexture->height() : 0;
     }
 
     /**
@@ -143,7 +141,7 @@
      * Can return 0 if the atlas is not initialized.
      */
     GLuint getTexture() const {
-        return mTexture ? mTexture->id : 0;
+        return mTexture ? mTexture->id() : 0;
     }
 
     /**
@@ -160,7 +158,6 @@
 
 private:
     void createEntries(Caches& caches, int64_t* map, int count);
-    void updateTextureId();
 
     Texture* mTexture;
     Image* mImage;
@@ -168,7 +165,7 @@
     const bool mBlendKey;
     const bool mOpaqueKey;
 
-    KeyedVector<const SkPixelRef*, Entry*> mEntries;
+    std::unordered_map<const SkPixelRef*, std::unique_ptr<Entry>> mEntries;
 }; // class AssetAtlas
 
 }; // namespace uirenderer
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 5b34f6b..00381ee 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -217,7 +217,7 @@
             .setMeshTexturedUnitQuad(nullptr)
             .setFillShadowTexturePaint(*texture, textShadow.color, *op.paint, state.alpha)
             .setTransform(state.computedState.transform, TransformFlags::None)
-            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height))
+            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width(), sy + texture->height()))
             .build();
     renderer.renderGlop(state, glop);
 }
@@ -337,7 +337,7 @@
 
 static void renderPathTexture(BakedOpRenderer& renderer, const BakedOpState& state,
         PathTexture& texture, const RecordedOp& op) {
-    Rect dest(texture.width, texture.height);
+    Rect dest(texture.width(), texture.height());
     dest.translate(texture.left - texture.offset,
             texture.top - texture.offset);
     Glop glop;
@@ -399,7 +399,7 @@
             .setMeshTexturedUnitQuad(texture->uvMapper)
             .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
             .setTransform(state.computedState.transform, TransformFlags::None)
-            .setModelViewMapUnitToRectSnap(Rect(texture->width, texture->height))
+            .setModelViewMapUnitToRectSnap(Rect(texture->width(), texture->height()))
             .build();
     renderer.renderGlop(state, glop);
 }
@@ -483,10 +483,10 @@
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
 
-    Rect uv(std::max(0.0f, op.src.left / texture->width),
-            std::max(0.0f, op.src.top / texture->height),
-            std::min(1.0f, op.src.right / texture->width),
-            std::min(1.0f, op.src.bottom / texture->height));
+    Rect uv(std::max(0.0f, op.src.left / texture->width()),
+            std::max(0.0f, op.src.top / texture->height()),
+            std::min(1.0f, op.src.right / texture->width()),
+            std::min(1.0f, op.src.bottom / texture->height()));
 
     const int textureFillFlags = (op.bitmap->colorType() == kAlpha_8_SkColorType)
             ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
@@ -784,6 +784,9 @@
                 .build();
         renderer.renderGlop(state, glop);
     }
+    GL_CHECKPOINT();
+    renderer.renderState().layerPool().putOrDelete(*op.layerHandle);
+    GL_CHECKPOINT();
 }
 
 } // namespace uirenderer
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 42fb66f..e65746e 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -48,7 +48,7 @@
 
     // attach the texture to the FBO
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-            offscreenBuffer->texture.id, 0);
+            offscreenBuffer->texture.id(), 0);
     LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "startLayer FAILED");
     LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
             "framebuffer incomplete!");
@@ -74,7 +74,8 @@
 
     // Detach the texture from the FBO
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
-    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "endLayer FAILED");
+    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "endLayer FAILED, bound fbo = %u",
+            mRenderState.getFramebuffer());
     mRenderState.deleteFramebuffer(mRenderTarget.frameBufferId);
     mRenderTarget.frameBufferId = 0;
 }
@@ -84,7 +85,7 @@
             area.getWidth(), area.getHeight());
     if (!area.isEmpty()) {
         mCaches.textureState().activateTexture(0);
-        mCaches.textureState().bindTexture(buffer->texture.id);
+        mCaches.textureState().bindTexture(buffer->texture.id());
 
         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
                 area.left, mRenderTarget.viewportHeight - area.bottom,
@@ -138,9 +139,7 @@
     mCaches.pathCache.trim();
     mCaches.tessellationCache.trim();
 
-#if DEBUG_OPENGL
-    GLUtils::dumpGLErrors();
-#endif
+    GL_CHECKPOINT();
 
 #if DEBUG_MEMORY_USAGE
     mCaches.dumpMemoryUsage();
@@ -272,7 +271,7 @@
                     OffscreenBuffer* layer = mRenderTarget.offscreenBuffer;
                     mRenderTarget.stencil = mCaches.renderBufferCache.get(
                             Stencil::getLayerStencilFormat(),
-                            layer->texture.width, layer->texture.height);
+                            layer->texture.width(), layer->texture.height());
                     // stencil is bound + allocated - associate it with current FBO
                     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                             GL_RENDERBUFFER, mRenderTarget.stencil->getName());
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index e857f6b..10c4698 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -45,9 +45,15 @@
      * Position agnostic shadow lighting info. Used with all shadow ops in scene.
      */
     struct LightInfo {
-        float lightRadius = 0;
-        uint8_t ambientShadowAlpha = 0;
-        uint8_t spotShadowAlpha = 0;
+        LightInfo() : LightInfo(0, 0, 0) {}
+        LightInfo(float lightRadius, uint8_t ambientShadowAlpha,
+                uint8_t spotShadowAlpha)
+                : lightRadius(lightRadius)
+                , ambientShadowAlpha(ambientShadowAlpha)
+                , spotShadowAlpha(spotShadowAlpha) {}
+        float lightRadius;
+        uint8_t ambientShadowAlpha;
+        uint8_t spotShadowAlpha;
     };
 
     BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, const LightInfo& lightInfo)
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/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 166656c..c4c655b 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -51,20 +51,25 @@
     // updated in the order they're passed in (mLayerBuilders are issued to Renderer in reverse)
     for (int i = layers.entries().size() - 1; i >= 0; i--) {
         RenderNode* layerNode = layers.entries()[i].renderNode;
-        const Rect& layerDamage = layers.entries()[i].damage;
-        layerNode->computeOrdering();
+        // only schedule repaint if node still on layer - possible it may have been
+        // removed during a dropped frame, but layers may still remain scheduled so
+        // as not to lose info on what portion is damaged
+        if (CC_LIKELY(layerNode->getLayer() != nullptr)) {
+            const Rect& layerDamage = layers.entries()[i].damage;
+            layerNode->computeOrdering();
 
-        // map current light center into RenderNode's coordinate space
-        Vector3 lightCenter = mCanvasState.currentSnapshot()->getRelativeLightCenter();
-        layerNode->getLayer()->inverseTransformInWindow.mapPoint3d(lightCenter);
+            // map current light center into RenderNode's coordinate space
+            Vector3 lightCenter = mCanvasState.currentSnapshot()->getRelativeLightCenter();
+            layerNode->getLayer()->inverseTransformInWindow.mapPoint3d(lightCenter);
 
-        saveForLayer(layerNode->getWidth(), layerNode->getHeight(), 0, 0,
-                layerDamage, lightCenter, nullptr, layerNode);
+            saveForLayer(layerNode->getWidth(), layerNode->getHeight(), 0, 0,
+                    layerDamage, lightCenter, nullptr, layerNode);
 
-        if (layerNode->getDisplayList()) {
-            deferNodeOps(*layerNode);
+            if (layerNode->getDisplayList()) {
+                deferNodeOps(*layerNode);
+            }
+            restoreForLayer();
         }
-        restoreForLayer();
     }
 
     // Defer Fbo0
diff --git a/libs/hwui/FrameBuilder.h b/libs/hwui/FrameBuilder.h
index 3ba73f0..bd01850 100644
--- a/libs/hwui/FrameBuilder.h
+++ b/libs/hwui/FrameBuilder.h
@@ -21,6 +21,7 @@
 #include "DisplayList.h"
 #include "LayerBuilder.h"
 #include "RecordedOp.h"
+#include "utils/GLUtils.h"
 
 #include <vector>
 #include <unordered_map>
@@ -99,22 +100,30 @@
         // Relay through layers in reverse order, since layers
         // later in the list will be drawn by earlier ones
         for (int i = mLayerBuilders.size() - 1; i >= 1; i--) {
+            GL_CHECKPOINT();
             LayerBuilder& layer = *(mLayerBuilders[i]);
             if (layer.renderNode) {
                 // cached HW layer - can't skip layer if empty
                 renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect);
+                GL_CHECKPOINT();
                 layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
+                GL_CHECKPOINT();
                 renderer.endLayer();
             } else if (!layer.empty()) { // save layer - skip entire layer if empty
                 layer.offscreenBuffer = renderer.startTemporaryLayer(layer.width, layer.height);
+                GL_CHECKPOINT();
                 layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
+                GL_CHECKPOINT();
                 renderer.endLayer();
             }
         }
 
+        GL_CHECKPOINT();
         const LayerBuilder& fbo0 = *(mLayerBuilders[0]);
         renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect);
+        GL_CHECKPOINT();
         fbo0.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
+        GL_CHECKPOINT();
         renderer.endFrame(fbo0.repaintRect);
     }
 
diff --git a/libs/hwui/GpuMemoryTracker.cpp b/libs/hwui/GpuMemoryTracker.cpp
new file mode 100644
index 0000000..4fb5701
--- /dev/null
+++ b/libs/hwui/GpuMemoryTracker.cpp
@@ -0,0 +1,140 @@
+/*
+ * 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 "utils/StringUtils.h"
+#include "Texture.h"
+
+#include <cutils/compiler.h>
+#include <GpuMemoryTracker.h>
+#include <utils/Trace.h>
+#include <array>
+#include <sstream>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+namespace uirenderer {
+
+pthread_t gGpuThread = 0;
+
+#define NUM_TYPES static_cast<int>(GpuObjectType::TypeCount)
+
+const char* TYPE_NAMES[] = {
+        "Texture",
+        "OffscreenBuffer",
+        "Layer",
+};
+
+struct TypeStats {
+    int totalSize = 0;
+    int count = 0;
+};
+
+static std::array<TypeStats, NUM_TYPES> gObjectStats;
+static std::unordered_set<GpuMemoryTracker*> gObjectSet;
+
+void GpuMemoryTracker::notifySizeChanged(int newSize) {
+    int delta = newSize - mSize;
+    mSize = newSize;
+    gObjectStats[static_cast<int>(mType)].totalSize += delta;
+}
+
+void GpuMemoryTracker::startTrackingObject() {
+    auto result = gObjectSet.insert(this);
+    LOG_ALWAYS_FATAL_IF(!result.second,
+            "startTrackingObject() on %p failed, already being tracked!", this);
+    gObjectStats[static_cast<int>(mType)].count++;
+}
+
+void GpuMemoryTracker::stopTrackingObject() {
+    size_t removed = gObjectSet.erase(this);
+    LOG_ALWAYS_FATAL_IF(removed != 1,
+            "stopTrackingObject removed %zd, is %p not being tracked?",
+            removed, this);
+    gObjectStats[static_cast<int>(mType)].count--;
+}
+
+void GpuMemoryTracker::onGLContextCreated() {
+    LOG_ALWAYS_FATAL_IF(gGpuThread != 0, "We already have a GL thread? "
+            "current = %lu, gl thread = %lu", pthread_self(), gGpuThread);
+    gGpuThread = pthread_self();
+}
+
+void GpuMemoryTracker::onGLContextDestroyed() {
+    gGpuThread = 0;
+    if (CC_UNLIKELY(gObjectSet.size() > 0)) {
+        std::stringstream os;
+        dump(os);
+        ALOGE("%s", os.str().c_str());
+        LOG_ALWAYS_FATAL("Leaked %zd GPU objects!", gObjectSet.size());
+    }
+}
+
+void GpuMemoryTracker::dump() {
+    std::stringstream strout;
+    dump(strout);
+    ALOGD("%s", strout.str().c_str());
+}
+
+void GpuMemoryTracker::dump(std::ostream& stream) {
+    for (int type = 0; type < NUM_TYPES; type++) {
+        const TypeStats& stats = gObjectStats[type];
+        stream << TYPE_NAMES[type];
+        stream << " is using " << SizePrinter{stats.totalSize};
+        stream << ", count = " << stats.count;
+        stream << std::endl;
+    }
+}
+
+int GpuMemoryTracker::getInstanceCount(GpuObjectType type) {
+    return gObjectStats[static_cast<int>(type)].count;
+}
+
+int GpuMemoryTracker::getTotalSize(GpuObjectType type) {
+    return gObjectStats[static_cast<int>(type)].totalSize;
+}
+
+void GpuMemoryTracker::onFrameCompleted() {
+    if (ATRACE_ENABLED()) {
+        char buf[128];
+        for (int type = 0; type < NUM_TYPES; type++) {
+            snprintf(buf, 128, "hwui_%s", TYPE_NAMES[type]);
+            const TypeStats& stats = gObjectStats[type];
+            ATRACE_INT(buf, stats.totalSize);
+            snprintf(buf, 128, "hwui_%s_count", TYPE_NAMES[type]);
+            ATRACE_INT(buf, stats.count);
+        }
+    }
+
+    std::vector<const Texture*> freeList;
+    for (const auto& obj : gObjectSet) {
+        if (obj->objectType() == GpuObjectType::Texture) {
+            const Texture* texture = static_cast<Texture*>(obj);
+            if (texture->cleanup) {
+                ALOGE("Leaked texture marked for cleanup! id=%u, size %ux%u",
+                        texture->id(), texture->width(), texture->height());
+                freeList.push_back(texture);
+            }
+        }
+    }
+    for (auto& texture : freeList) {
+        const_cast<Texture*>(texture)->deleteTexture();
+        delete texture;
+    }
+}
+
+} // namespace uirenderer
+} // namespace android;
diff --git a/libs/hwui/GpuMemoryTracker.h b/libs/hwui/GpuMemoryTracker.h
new file mode 100644
index 0000000..851aeae
--- /dev/null
+++ b/libs/hwui/GpuMemoryTracker.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <cutils/log.h>
+#include <pthread.h>
+#include <ostream>
+
+namespace android {
+namespace uirenderer {
+
+extern pthread_t gGpuThread;
+
+#define ASSERT_GPU_THREAD() LOG_ALWAYS_FATAL_IF( \
+        !pthread_equal(gGpuThread, pthread_self()), \
+        "Error, %p of type %d (size=%d) used on wrong thread! cur thread %lu " \
+        "!= gpu thread %lu", this, static_cast<int>(mType), mSize, \
+        pthread_self(), gGpuThread)
+
+enum class GpuObjectType {
+    Texture = 0,
+    OffscreenBuffer,
+    Layer,
+
+    TypeCount,
+};
+
+class GpuMemoryTracker {
+public:
+    GpuObjectType objectType() { return mType; }
+    int objectSize() { return mSize; }
+
+    static void onGLContextCreated();
+    static void onGLContextDestroyed();
+    static void dump();
+    static void dump(std::ostream& stream);
+    static int getInstanceCount(GpuObjectType type);
+    static int getTotalSize(GpuObjectType type);
+    static void onFrameCompleted();
+
+protected:
+    GpuMemoryTracker(GpuObjectType type) : mType(type) {
+        ASSERT_GPU_THREAD();
+        startTrackingObject();
+    }
+
+    ~GpuMemoryTracker() {
+        notifySizeChanged(0);
+        stopTrackingObject();
+    }
+
+    void notifySizeChanged(int newSize);
+
+private:
+    void startTrackingObject();
+    void stopTrackingObject();
+
+    int mSize = 0;
+    GpuObjectType mType;
+};
+
+} // namespace uirenderer
+} // namespace android;
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 8c46450..e899ac7 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -110,9 +110,7 @@
 
 void GradientCache::operator()(GradientCacheEntry&, Texture*& texture) {
     if (texture) {
-        const uint32_t size = texture->width * texture->height * bytesPerPixel();
-        mSize -= size;
-
+        mSize -= texture->objectSize();
         texture->deleteTexture();
         delete texture;
     }
@@ -167,18 +165,16 @@
     getGradientInfo(colors, count, info);
 
     Texture* texture = new Texture(Caches::getInstance());
-    texture->width = info.width;
-    texture->height = 2;
     texture->blend = info.hasAlpha;
     texture->generation = 1;
 
     // Asume the cache is always big enough
-    const uint32_t size = texture->width * texture->height * bytesPerPixel();
+    const uint32_t size = info.width * 2 * bytesPerPixel();
     while (getSize() + size > mMaxSize) {
         mCache.removeOldest();
     }
 
-    generateTexture(colors, positions, texture);
+    generateTexture(colors, positions, info.width, 2, texture);
 
     mSize += size;
     mCache.put(gradient, texture);
@@ -231,10 +227,10 @@
     dst += 4 * sizeof(float);
 }
 
-void GradientCache::generateTexture(uint32_t* colors, float* positions, Texture* texture) {
-    const uint32_t width = texture->width;
+void GradientCache::generateTexture(uint32_t* colors, float* positions,
+        const uint32_t width, const uint32_t height, Texture* texture) {
     const GLsizei rowBytes = width * bytesPerPixel();
-    uint8_t pixels[rowBytes * texture->height];
+    uint8_t pixels[rowBytes * height];
 
     static ChannelSplitter gSplitters[] = {
             &android::uirenderer::GradientCache::splitToBytes,
@@ -277,17 +273,11 @@
 
     memcpy(pixels + rowBytes, pixels, rowBytes);
 
-    glGenTextures(1, &texture->id);
-    Caches::getInstance().textureState().bindTexture(texture->id);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
     if (mUseFloatTexture) {
         // We have to use GL_RGBA16F because GL_RGBA32F does not support filtering
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, texture->height, 0,
-                GL_RGBA, GL_FLOAT, pixels);
+        texture->upload(GL_RGBA16F, width, height, GL_RGBA, GL_FLOAT, pixels);
     } else {
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, texture->height, 0,
-                GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+        texture->upload(GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
     }
 
     texture->setFilter(GL_LINEAR);
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 7534c5d..b762ca7 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -143,7 +143,8 @@
     Texture* addLinearGradient(GradientCacheEntry& gradient,
             uint32_t* colors, float* positions, int count);
 
-    void generateTexture(uint32_t* colors, float* positions, Texture* texture);
+    void generateTexture(uint32_t* colors, float* positions,
+            const uint32_t width, const uint32_t height, Texture* texture);
 
     struct GradientInfo {
         uint32_t width;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 0fe20ad..114347d 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -36,7 +36,8 @@
 namespace uirenderer {
 
 Layer::Layer(Type layerType, RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
-        : state(State::Uncached)
+        : GpuMemoryTracker(GpuObjectType::Layer)
+        , state(State::Uncached)
         , caches(Caches::getInstance())
         , renderState(renderState)
         , texture(caches)
@@ -45,8 +46,8 @@
     // preserves the old inc/dec ref locations. This should be changed...
     incStrong(nullptr);
     renderTarget = GL_TEXTURE_2D;
-    texture.width = layerWidth;
-    texture.height = layerHeight;
+    texture.mWidth = layerWidth;
+    texture.mHeight = layerHeight;
     renderState.registerLayer(this);
 }
 
@@ -54,10 +55,9 @@
     renderState.unregisterLayer(this);
     SkSafeUnref(colorFilter);
 
-    if (stencil || fbo || texture.id) {
-        renderState.requireGLContext();
+    if (stencil || fbo || texture.mId) {
         removeFbo();
-        deleteTexture();
+        texture.deleteTexture();
     }
 
     delete[] mesh;
@@ -65,7 +65,7 @@
 
 void Layer::onGlContextLost() {
     removeFbo();
-    deleteTexture();
+    texture.deleteTexture();
 }
 
 uint32_t Layer::computeIdealWidth(uint32_t layerWidth) {
@@ -179,8 +179,8 @@
 }
 
 void Layer::bindTexture() const {
-    if (texture.id) {
-        caches.textureState().bindTexture(renderTarget, texture.id);
+    if (texture.mId) {
+        caches.textureState().bindTexture(renderTarget, texture.mId);
     }
 }
 
@@ -191,29 +191,22 @@
 }
 
 void Layer::generateTexture() {
-    if (!texture.id) {
-        glGenTextures(1, &texture.id);
-    }
-}
-
-void Layer::deleteTexture() {
-    if (texture.id) {
-        texture.deleteTexture();
-        texture.id = 0;
+    if (!texture.mId) {
+        glGenTextures(1, &texture.mId);
     }
 }
 
 void Layer::clearTexture() {
-    caches.textureState().unbindTexture(texture.id);
-    texture.id = 0;
+    caches.textureState().unbindTexture(texture.mId);
+    texture.mId = 0;
 }
 
 void Layer::allocateTexture() {
 #if DEBUG_LAYERS
     ALOGD("  Allocate layer: %dx%d", getWidth(), getHeight());
 #endif
-    if (texture.id) {
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    if (texture.mId) {
+        texture.updateSize(getWidth(), getHeight(), GL_RGBA);
         glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
     }
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index e90f055..e00ae66 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -24,6 +24,7 @@
 #include <memory>
 
 #include <GLES2/gl2.h>
+#include <GpuMemoryTracker.h>
 
 #include <ui/Region.h>
 
@@ -54,7 +55,7 @@
 /**
  * A layer has dimensions and is backed by an OpenGL texture or FBO.
  */
-class Layer : public VirtualLightRefBase {
+class Layer : public VirtualLightRefBase, GpuMemoryTracker {
 public:
     enum class Type {
         Texture,
@@ -94,8 +95,8 @@
         regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
                bounds.rightBottom().x, bounds.rightBottom().y);
 
-        const float texX = 1.0f / float(texture.width);
-        const float texY = 1.0f / float(texture.height);
+        const float texX = 1.0f / float(texture.mWidth);
+        const float texY = 1.0f / float(texture.mHeight);
         const float height = layer.getHeight();
         texCoords.set(
                regionRect.left * texX, (height - regionRect.top) * texY,
@@ -112,11 +113,11 @@
     void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom);
 
     inline uint32_t getWidth() const {
-        return texture.width;
+        return texture.mWidth;
     }
 
     inline uint32_t getHeight() const {
-        return texture.height;
+        return texture.mHeight;
     }
 
     /**
@@ -131,8 +132,7 @@
     bool resize(const uint32_t width, const uint32_t height);
 
     void setSize(uint32_t width, uint32_t height) {
-        texture.width = width;
-        texture.height = height;
+        texture.updateSize(width, height, texture.format());
     }
 
     ANDROID_API void setPaint(const SkPaint* paint);
@@ -201,7 +201,7 @@
     }
 
     inline GLuint getTextureId() const {
-        return texture.id;
+        return texture.id();
     }
 
     inline Texture& getTexture() {
@@ -263,7 +263,6 @@
     void bindTexture() const;
     void generateTexture();
     void allocateTexture();
-    void deleteTexture();
 
     /**
      * When the caller frees the texture itself, the caller
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index b117754..f5681ce 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -112,7 +112,6 @@
         layer->bindTexture();
         layer->setFilter(GL_NEAREST);
         layer->setWrap(GL_CLAMP_TO_EDGE, false);
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
 #if DEBUG_LAYERS
         dump();
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 92b758d..1bfa308 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <GpuMemoryTracker.h>
 #include "OpenGLRenderer.h"
 
 #include "DeferredDisplayList.h"
@@ -194,12 +195,11 @@
     }
 
     if (!suppressErrorChecks()) {
-#if DEBUG_OPENGL
-        GLUtils::dumpGLErrors();
-#endif
+        GL_CHECKPOINT();
 
 #if DEBUG_MEMORY_USAGE
         mCaches.dumpMemoryUsage();
+        GPUMemoryTracker::dump();
 #else
         if (Properties::debugLevel & kDebugMemory) {
             mCaches.dumpMemoryUsage();
@@ -1497,7 +1497,7 @@
             .setMeshTexturedUnitQuad(texture->uvMapper)
             .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
             .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewMapUnitToRectSnap(Rect(texture->width, texture->height))
+            .setModelViewMapUnitToRectSnap(Rect(texture->width(), texture->height()))
             .build();
     renderGlop(glop);
 }
@@ -1601,10 +1601,10 @@
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
 
-    Rect uv(std::max(0.0f, src.left / texture->width),
-            std::max(0.0f, src.top / texture->height),
-            std::min(1.0f, src.right / texture->width),
-            std::min(1.0f, src.bottom / texture->height));
+    Rect uv(std::max(0.0f, src.left / texture->width()),
+            std::max(0.0f, src.top / texture->height()),
+            std::min(1.0f, src.right / texture->width()),
+            std::min(1.0f, src.bottom / texture->height()));
 
     const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType)
             ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
@@ -1977,7 +1977,7 @@
             .setMeshTexturedUnitQuad(nullptr)
             .setFillShadowTexturePaint(*texture, textShadow.color, *paint, currentSnapshot()->alpha)
             .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height))
+            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width(), sy + texture->height()))
             .build();
     renderGlop(glop);
 }
@@ -2316,7 +2316,7 @@
 
 void OpenGLRenderer::drawPathTexture(PathTexture* texture, float x, float y,
         const SkPaint* paint) {
-    if (quickRejectSetupScissor(x, y, x + texture->width, y + texture->height)) {
+    if (quickRejectSetupScissor(x, y, x + texture->width(), y + texture->height())) {
         return;
     }
 
@@ -2326,7 +2326,7 @@
             .setMeshTexturedUnitQuad(nullptr)
             .setFillPathTexturePaint(*texture, *paint, currentSnapshot()->alpha)
             .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewMapUnitToRect(Rect(x, y, x + texture->width, y + texture->height))
+            .setModelViewMapUnitToRect(Rect(x, y, x + texture->width(), y + texture->height()))
             .build();
     renderGlop(glop);
 }
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 06ea55a..bfabc1d 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -185,7 +185,7 @@
 
 void PathCache::removeTexture(PathTexture* texture) {
     if (texture) {
-        const uint32_t size = texture->width * texture->height;
+        const uint32_t size = texture->width() * texture->height();
 
         // If there is a pending task we must wait for it to return
         // before attempting our cleanup
@@ -209,9 +209,7 @@
             ALOGD("Shape deleted, size = %d", size);
         }
 
-        if (texture->id) {
-            Caches::getInstance().textureState().deleteTexture(texture->id);
-        }
+        texture->deleteTexture();
         delete texture;
     }
 }
@@ -248,8 +246,7 @@
     drawPath(path, paint, bitmap, left, top, offset, width, height);
 
     PathTexture* texture = new PathTexture(Caches::getInstance(),
-            left, top, offset, width, height,
-            path->getGenerationID());
+            left, top, offset, path->getGenerationID());
     generateTexture(entry, &bitmap, texture);
 
     return texture;
@@ -262,7 +259,7 @@
     // Note here that we upload to a texture even if it's bigger than mMaxSize.
     // Such an entry in mCache will only be temporary, since it will be evicted
     // immediately on trim, or on any other Path entering the cache.
-    uint32_t size = texture->width * texture->height;
+    uint32_t size = texture->width() * texture->height();
     mSize += size;
     PATH_LOGD("PathCache::get/create: name, size, mSize = %d, %d, %d",
             texture->id, size, mSize);
@@ -280,24 +277,8 @@
 
 void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
     ATRACE_NAME("Upload Path Texture");
-    SkAutoLockPixels alp(bitmap);
-    if (!bitmap.readyToDraw()) {
-        ALOGE("Cannot generate texture from bitmap");
-        return;
-    }
-
-    glGenTextures(1, &texture->id);
-
-    Caches::getInstance().textureState().bindTexture(texture->id);
-    // Textures are Alpha8
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
-    texture->blend = true;
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
-            GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
-
+    texture->upload(bitmap);
     texture->setFilter(GL_LINEAR);
-    texture->setWrap(GL_CLAMP_TO_EDGE);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -320,16 +301,12 @@
     texture->left = left;
     texture->top = top;
     texture->offset = offset;
-    texture->width = width;
-    texture->height = height;
 
     if (width <= mMaxTextureSize && height <= mMaxTextureSize) {
         SkBitmap* bitmap = new SkBitmap();
         drawPath(&t->path, &t->paint, *bitmap, left, top, offset, width, height);
         t->setResult(bitmap);
     } else {
-        texture->width = 0;
-        texture->height = 0;
         t->setResult(nullptr);
     }
 }
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 302e9f8..18f380f 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -61,13 +61,11 @@
  */
 struct PathTexture: public Texture {
     PathTexture(Caches& caches, float left, float top,
-            float offset, int width, int height, int generation)
+            float offset, int generation)
             : Texture(caches)
             , left(left)
             , top(top)
             , offset(offset) {
-        this->width = width;
-        this->height = height;
         this->generation = generation;
     }
     PathTexture(Caches& caches, int generation)
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/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 83652c6..6f4a683 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -57,7 +57,7 @@
 }
 
 static inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) {
-    caches->textureState().bindTexture(texture->id);
+    caches->textureState().bindTexture(texture->id());
     texture->setWrapST(wrapS, wrapT);
 }
 
@@ -219,8 +219,8 @@
 
     outData->bitmapSampler = (*textureUnit)++;
 
-    const float width = outData->bitmapTexture->width;
-    const float height = outData->bitmapTexture->height;
+    const float width = outData->bitmapTexture->width();
+    const float height = outData->bitmapTexture->height();
 
     description->hasBitmap = true;
     if (!caches.extensions().hasNPot()
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 51f1652..62a20fc 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -187,13 +187,10 @@
         texture = new ShadowTexture(caches);
         texture->left = shadow.penX;
         texture->top = shadow.penY;
-        texture->width = shadow.width;
-        texture->height = shadow.height;
         texture->generation = 0;
         texture->blend = true;
 
         const uint32_t size = shadow.width * shadow.height;
-        texture->bitmapSize = size;
 
         // Don't even try to cache a bitmap that's bigger than the cache
         if (size < mMaxSize) {
@@ -202,15 +199,9 @@
             }
         }
 
-        glGenTextures(1, &texture->id);
-
-        caches.textureState().bindTexture(texture->id);
         // Textures are Alpha8
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
+        texture->upload(GL_ALPHA, shadow.width, shadow.height,
                 GL_ALPHA, GL_UNSIGNED_BYTE, shadow.image);
-
         texture->setFilter(GL_LINEAR);
         texture->setWrap(GL_CLAMP_TO_EDGE);
 
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 5195b45..c5000e4 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -14,14 +14,30 @@
  * limitations under the License.
  */
 
-#include <utils/Log.h>
-
 #include "Caches.h"
 #include "Texture.h"
+#include "utils/GLUtils.h"
+#include "utils/TraceUtils.h"
+
+#include <utils/Log.h>
+
+#include <SkCanvas.h>
 
 namespace android {
 namespace uirenderer {
 
+static int bytesPerPixel(GLint glFormat) {
+    switch (glFormat) {
+    case GL_ALPHA:
+        return 1;
+    case GL_RGB:
+        return 3;
+    case GL_RGBA:
+    default:
+        return 4;
+    }
+}
+
 void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force,
         GLenum renderTarget) {
 
@@ -32,7 +48,7 @@
         mWrapT = wrapT;
 
         if (bindTexture) {
-            mCaches.textureState().bindTexture(renderTarget, id);
+            mCaches.textureState().bindTexture(renderTarget, mId);
         }
 
         glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
@@ -50,7 +66,7 @@
         mMagFilter = mag;
 
         if (bindTexture) {
-            mCaches.textureState().bindTexture(renderTarget, id);
+            mCaches.textureState().bindTexture(renderTarget, mId);
         }
 
         if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
@@ -60,8 +76,187 @@
     }
 }
 
-void Texture::deleteTexture() const {
-    mCaches.textureState().deleteTexture(id);
+void Texture::deleteTexture() {
+    mCaches.textureState().deleteTexture(mId);
+    mId = 0;
+}
+
+bool Texture::updateSize(uint32_t width, uint32_t height, GLint format) {
+    if (mWidth == width && mHeight == height && mFormat == format) {
+        return false;
+    }
+    mWidth = width;
+    mHeight = height;
+    mFormat = format;
+    notifySizeChanged(mWidth * mHeight * bytesPerPixel(mFormat));
+    return true;
+}
+
+void Texture::upload(GLint internalformat, uint32_t width, uint32_t height,
+        GLenum format, GLenum type, const void* pixels) {
+    GL_CHECKPOINT();
+    mCaches.textureState().activateTexture(0);
+    bool needsAlloc = updateSize(width, height, internalformat);
+    if (!mId) {
+        glGenTextures(1, &mId);
+        needsAlloc = true;
+    }
+    mCaches.textureState().bindTexture(GL_TEXTURE_2D, mId);
+    if (needsAlloc) {
+        glTexImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
+                format, type, pixels);
+    } else if (pixels) {
+        glTexSubImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
+                format, type, pixels);
+    }
+    GL_CHECKPOINT();
+}
+
+static void uploadToTexture(bool resize, GLenum format, GLenum type, GLsizei stride, GLsizei bpp,
+        GLsizei width, GLsizei height, const GLvoid * data) {
+
+    const bool useStride = stride != width
+            && Caches::getInstance().extensions().hasUnpackRowLength();
+    if ((stride == width) || useStride) {
+        if (useStride) {
+            glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
+        }
+
+        if (resize) {
+            glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data);
+        } else {
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data);
+        }
+
+        if (useStride) {
+            glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+        }
+    } else {
+        //  With OpenGL ES 2.0 we need to copy the bitmap in a temporary buffer
+        //  if the stride doesn't match the width
+
+        GLvoid * temp = (GLvoid *) malloc(width * height * bpp);
+        if (!temp) return;
+
+        uint8_t * pDst = (uint8_t *)temp;
+        uint8_t * pSrc = (uint8_t *)data;
+        for (GLsizei i = 0; i < height; i++) {
+            memcpy(pDst, pSrc, width * bpp);
+            pDst += width * bpp;
+            pSrc += stride * bpp;
+        }
+
+        if (resize) {
+            glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, temp);
+        } else {
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, temp);
+        }
+
+        free(temp);
+    }
+}
+
+static void uploadSkBitmapToTexture(const SkBitmap& bitmap,
+        bool resize, GLenum format, GLenum type) {
+    uploadToTexture(resize, format, type, bitmap.rowBytesAsPixels(), bitmap.bytesPerPixel(),
+            bitmap.width(), bitmap.height(), bitmap.getPixels());
+}
+
+static void colorTypeToGlFormatAndType(SkColorType colorType,
+        GLint* outFormat, GLint* outType) {
+    switch (colorType) {
+    case kAlpha_8_SkColorType:
+        *outFormat = GL_ALPHA;
+        *outType = GL_UNSIGNED_BYTE;
+        break;
+    case kRGB_565_SkColorType:
+        *outFormat = GL_RGB;
+        *outType = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    // ARGB_4444 and Index_8 are both upconverted to RGBA_8888
+    case kARGB_4444_SkColorType:
+    case kIndex_8_SkColorType:
+    case kN32_SkColorType:
+        *outFormat = GL_RGBA;
+        *outType = GL_UNSIGNED_BYTE;
+        break;
+    default:
+        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", colorType);
+        break;
+    }
+}
+
+void Texture::upload(const SkBitmap& bitmap) {
+    SkAutoLockPixels alp(bitmap);
+
+    if (!bitmap.readyToDraw()) {
+        ALOGE("Cannot generate texture from bitmap");
+        return;
+    }
+
+    ATRACE_FORMAT("Upload %ux%u Texture", bitmap.width(), bitmap.height());
+
+    // We could also enable mipmapping if both bitmap dimensions are powers
+    // of 2 but we'd have to deal with size changes. Let's keep this simple
+    const bool canMipMap = mCaches.extensions().hasNPot();
+
+    // If the texture had mipmap enabled but not anymore,
+    // force a glTexImage2D to discard the mipmap levels
+    bool needsAlloc = canMipMap && mipMap && !bitmap.hasHardwareMipMap();
+
+    if (!mId) {
+        glGenTextures(1, &mId);
+        needsAlloc = true;
+    }
+
+    GLint format, type;
+    colorTypeToGlFormatAndType(bitmap.colorType(), &format, &type);
+
+    if (updateSize(bitmap.width(), bitmap.height(), format)) {
+        needsAlloc = true;
+    }
+
+    blend = !bitmap.isOpaque();
+    mCaches.textureState().bindTexture(mId);
+
+    if (CC_UNLIKELY(bitmap.colorType() == kARGB_4444_SkColorType
+            || bitmap.colorType() == kIndex_8_SkColorType)) {
+        SkBitmap rgbaBitmap;
+        rgbaBitmap.allocPixels(SkImageInfo::MakeN32(mWidth, mHeight,
+                bitmap.alphaType()));
+        rgbaBitmap.eraseColor(0);
+
+        SkCanvas canvas(rgbaBitmap);
+        canvas.drawBitmap(bitmap, 0.0f, 0.0f, nullptr);
+
+        uploadSkBitmapToTexture(rgbaBitmap, needsAlloc, format, type);
+    } else {
+        uploadSkBitmapToTexture(bitmap, needsAlloc, format, type);
+    }
+
+    if (canMipMap) {
+        mipMap = bitmap.hasHardwareMipMap();
+        if (mipMap) {
+            glGenerateMipmap(GL_TEXTURE_2D);
+        }
+    }
+
+    if (mFirstFilter) {
+        setFilter(GL_NEAREST);
+    }
+
+    if (mFirstWrap) {
+        setWrap(GL_CLAMP_TO_EDGE);
+    }
+}
+
+void Texture::wrap(GLuint id, uint32_t width, uint32_t height, GLint format) {
+    mId = id;
+    mWidth = width;
+    mHeight = height;
+    mFormat = format;
+    // We're wrapping an existing texture, so don't double count this memory
+    notifySizeChanged(0);
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 1c544b9..4e8e6dc 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -17,20 +17,27 @@
 #ifndef ANDROID_HWUI_TEXTURE_H
 #define ANDROID_HWUI_TEXTURE_H
 
+#include "GpuMemoryTracker.h"
+
 #include <GLES2/gl2.h>
+#include <SkBitmap.h>
 
 namespace android {
 namespace uirenderer {
 
 class Caches;
 class UvMapper;
+class Layer;
 
 /**
  * Represents an OpenGL texture.
  */
-class Texture {
+class Texture : public GpuMemoryTracker {
 public:
-    Texture(Caches& caches) : mCaches(caches) { }
+    Texture(Caches& caches)
+        : GpuMemoryTracker(GpuObjectType::Texture)
+        , mCaches(caches)
+    { }
 
     virtual ~Texture() { }
 
@@ -53,12 +60,55 @@
     /**
      * Convenience method to call glDeleteTextures() on this texture's id.
      */
-    void deleteTexture() const;
+    void deleteTexture();
 
     /**
-     * Name of the texture.
+     * Sets the width, height, and format of the texture along with allocating
+     * the texture ID. Does nothing if the width, height, and format are already
+     * the requested values.
+     *
+     * The image data is undefined after calling this.
      */
-    GLuint id = 0;
+    void resize(uint32_t width, uint32_t height, GLint format) {
+        upload(format, width, height, format, GL_UNSIGNED_BYTE, nullptr);
+    }
+
+    /**
+     * Updates this Texture with the contents of the provided SkBitmap,
+     * also setting the appropriate width, height, and format. It is not necessary
+     * to call resize() prior to this.
+     *
+     * Note this does not set the generation from the SkBitmap.
+     */
+    void upload(const SkBitmap& source);
+
+    /**
+     * Basically glTexImage2D/glTexSubImage2D.
+     */
+    void upload(GLint internalformat, uint32_t width, uint32_t height,
+            GLenum format, GLenum type, const void* pixels);
+
+    /**
+     * Wraps an existing texture.
+     */
+    void wrap(GLuint id, uint32_t width, uint32_t height, GLint format);
+
+    GLuint id() const {
+        return mId;
+    }
+
+    uint32_t width() const {
+        return mWidth;
+    }
+
+    uint32_t height() const {
+        return mHeight;
+    }
+
+    GLint format() const {
+        return mFormat;
+    }
+
     /**
      * Generation of the backing bitmap,
      */
@@ -68,14 +118,6 @@
      */
     bool blend = false;
     /**
-     * Width of the backing bitmap.
-     */
-    uint32_t width = 0;
-    /**
-     * Height of the backing bitmap.
-     */
-    uint32_t height = 0;
-    /**
      * Indicates whether this texture should be cleaned up after use.
      */
     bool cleanup = false;
@@ -100,6 +142,19 @@
     void* isInUse = nullptr;
 
 private:
+    // TODO: Temporarily grant private access to Layer, remove once
+    // Layer can be de-tangled from being a dual-purpose render target
+    // and external texture wrapper
+    friend class Layer;
+
+    // Returns true if the size changed, false if it was the same
+    bool updateSize(uint32_t width, uint32_t height, GLint format);
+
+    GLuint mId = 0;
+    uint32_t mWidth = 0;
+    uint32_t mHeight = 0;
+    GLint mFormat = 0;
+
     /**
      * Last wrap modes set on this texture.
      */
@@ -120,7 +175,7 @@
 
 class AutoTexture {
 public:
-    AutoTexture(const Texture* texture)
+    AutoTexture(Texture* texture)
             : texture(texture) {}
     ~AutoTexture() {
         if (texture && texture->cleanup) {
@@ -129,7 +184,7 @@
         }
     }
 
-    const Texture *const texture;
+    Texture* const texture;
 }; // class AutoTexture
 
 }; // namespace uirenderer
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 21901cf..31bfa3a 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -166,7 +166,8 @@
         if (canCache) {
             texture = new Texture(Caches::getInstance());
             texture->bitmapSize = size;
-            Caches::getInstance().textureState().generateTexture(bitmap, texture, false);
+            texture->generation = bitmap->getGenerationID();
+            texture->upload(*bitmap);
 
             mSize += size;
             TEXTURE_LOGD("TextureCache::get: create texture(%p): name, size, mSize = %d, %d, %d",
@@ -179,7 +180,8 @@
     } else if (!texture->isInUse && bitmap->getGenerationID() != texture->generation) {
         // Texture was in the cache but is dirty, re-upload
         // TODO: Re-adjust the cache size if the bitmap's dimensions have changed
-        Caches::getInstance().textureState().generateTexture(bitmap, texture, true);
+        texture->upload(*bitmap);
+        texture->generation = bitmap->getGenerationID();
     }
 
     return texture;
@@ -204,7 +206,8 @@
         const uint32_t size = bitmap->rowBytes() * bitmap->height();
         texture = new Texture(Caches::getInstance());
         texture->bitmapSize = size;
-        Caches::getInstance().textureState().generateTexture(bitmap, texture, false);
+        texture->upload(*bitmap);
+        texture->generation = bitmap->getGenerationID();
         texture->cleanup = true;
     }
 
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 191c8a8..463450c 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -25,6 +25,7 @@
 #include "Debug.h"
 
 #include <vector>
+#include <unordered_map>
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 56cb104..793df92 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -407,8 +407,9 @@
     float canvasScaleY = 1.0f;
     if (mCanvasMatrix.getSkewX() == 0 && mCanvasMatrix.getSkewY() == 0) {
         // Only use the scale value when there's no skew or rotation in the canvas matrix.
-        canvasScaleX = mCanvasMatrix.getScaleX();
-        canvasScaleY = mCanvasMatrix.getScaleY();
+        // TODO: Add a cts test for drawing VD on a canvas with negative scaling factors.
+        canvasScaleX = fabs(mCanvasMatrix.getScaleX());
+        canvasScaleY = fabs(mCanvasMatrix.getScaleY());
     }
     int scaledWidth = (int) (mBounds.width() * canvasScaleX);
     int scaledHeight = (int) (mBounds.height() * canvasScaleY);
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index d2685da..8ba4761 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -111,11 +111,11 @@
 
 CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount)
         : mTexture(Caches::getInstance())
+        , mWidth(width)
+        , mHeight(height)
         , mFormat(format)
         , mMaxQuadCount(maxQuadCount)
         , mCaches(Caches::getInstance()) {
-    mTexture.width = width;
-    mTexture.height = height;
     mTexture.blend = true;
 
     mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
@@ -160,10 +160,7 @@
         delete mPixelBuffer;
         mPixelBuffer = nullptr;
     }
-    if (mTexture.id) {
-        mCaches.textureState().deleteTexture(mTexture.id);
-        mTexture.id = 0;
-    }
+    mTexture.deleteTexture();
     mDirty = false;
     mCurrentQuad = 0;
 }
@@ -183,22 +180,9 @@
         mPixelBuffer = PixelBuffer::create(mFormat, getWidth(), getHeight());
     }
 
-    if (!mTexture.id) {
-        glGenTextures(1, &mTexture.id);
-
-        mCaches.textureState().bindTexture(mTexture.id);
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-        // Initialize texture dimensions
-        glTexImage2D(GL_TEXTURE_2D, 0, mFormat, getWidth(), getHeight(), 0,
-                mFormat, GL_UNSIGNED_BYTE, nullptr);
-
-        const GLenum filtering = getLinearFiltering() ? GL_LINEAR : GL_NEAREST;
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
-
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    }
+    mTexture.resize(mWidth, mHeight, mFormat);
+    mTexture.setFilter(getLinearFiltering() ? GL_LINEAR : GL_NEAREST);
+    mTexture.setWrap(GL_CLAMP_TO_EDGE);
 }
 
 bool CacheTexture::upload() {
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index 6dabc76..5510666 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -92,11 +92,11 @@
     bool fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY);
 
     inline uint16_t getWidth() const {
-        return mTexture.width;
+        return mWidth;
     }
 
     inline uint16_t getHeight() const {
-        return mTexture.height;
+        return mHeight;
     }
 
     inline GLenum getFormat() const {
@@ -122,7 +122,7 @@
 
     GLuint getTextureId() {
         allocatePixelBuffer();
-        return mTexture.id;
+        return mTexture.id();
     }
 
     inline bool isDirty() const {
@@ -183,6 +183,7 @@
 
     PixelBuffer* mPixelBuffer = nullptr;
     Texture mTexture;
+    uint32_t mWidth, mHeight;
     GLenum mFormat;
     bool mLinearFiltering = false;
     bool mDirty = false;
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index 227b640..98c94df 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -34,29 +34,22 @@
 
 OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches,
         uint32_t viewportWidth, uint32_t viewportHeight)
-        : renderState(renderState)
+        : GpuMemoryTracker(GpuObjectType::OffscreenBuffer)
+        , renderState(renderState)
         , viewportWidth(viewportWidth)
         , viewportHeight(viewportHeight)
         , texture(caches) {
-    texture.width = computeIdealDimension(viewportWidth);
-    texture.height = computeIdealDimension(viewportHeight);
+    uint32_t width = computeIdealDimension(viewportWidth);
+    uint32_t height = computeIdealDimension(viewportHeight);
+    texture.resize(width, height, GL_RGBA);
     texture.blend = true;
-
-    caches.textureState().activateTexture(0);
-    glGenTextures(1, &texture.id);
-    caches.textureState().bindTexture(GL_TEXTURE_2D, texture.id);
-
-    texture.setWrap(GL_CLAMP_TO_EDGE, false, false, GL_TEXTURE_2D);
+    texture.setWrap(GL_CLAMP_TO_EDGE);
     // not setting filter on texture, since it's set when drawing, based on transform
-
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0,
-            GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
 }
 
 Rect OffscreenBuffer::getTextureCoordinates() {
-    const float texX = 1.0f / float(texture.width);
-    const float texY = 1.0f / float(texture.height);
+    const float texX = 1.0f / static_cast<float>(texture.width());
+    const float texY = 1.0f / static_cast<float>(texture.height());
     return Rect(0, viewportHeight * texY, viewportWidth * texX, 0);
 }
 
@@ -69,8 +62,8 @@
     size_t count;
     const android::Rect* rects = safeRegion.getArray(&count);
 
-    const float texX = 1.0f / float(texture.width);
-    const float texY = 1.0f / float(texture.height);
+    const float texX = 1.0f / float(texture.width());
+    const float texY = 1.0f / float(texture.height());
 
     FatVector<TextureVertex, 64> meshVector(count * 4); // uses heap if more than 64 vertices needed
     TextureVertex* mesh = &meshVector[0];
@@ -157,8 +150,8 @@
 OffscreenBuffer* OffscreenBufferPool::resize(OffscreenBuffer* layer,
         const uint32_t width, const uint32_t height) {
     RenderState& renderState = layer->renderState;
-    if (layer->texture.width == OffscreenBuffer::computeIdealDimension(width)
-            && layer->texture.height == OffscreenBuffer::computeIdealDimension(height)) {
+    if (layer->texture.width() == OffscreenBuffer::computeIdealDimension(width)
+            && layer->texture.height() == OffscreenBuffer::computeIdealDimension(height)) {
         // resize in place
         layer->viewportWidth = width;
         layer->viewportHeight = height;
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.h b/libs/hwui/renderstate/OffscreenBufferPool.h
index 2d8d529..94155ef 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.h
+++ b/libs/hwui/renderstate/OffscreenBufferPool.h
@@ -17,10 +17,10 @@
 #ifndef ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
 #define ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
 
+#include <GpuMemoryTracker.h>
 #include "Caches.h"
 #include "Texture.h"
 #include "utils/Macros.h"
-
 #include <ui/Region.h>
 
 #include <set>
@@ -40,7 +40,7 @@
  * viewport bounds, since textures are always allocated with width / height as a multiple of 64, for
  * the purpose of improving reuse.
  */
-class OffscreenBuffer {
+class OffscreenBuffer : GpuMemoryTracker {
 public:
     OffscreenBuffer(RenderState& renderState, Caches& caches,
             uint32_t viewportWidth, uint32_t viewportHeight);
@@ -58,7 +58,7 @@
 
     static uint32_t computeIdealDimension(uint32_t dimension);
 
-    uint32_t getSizeInBytes() { return texture.width * texture.height * 4; }
+    uint32_t getSizeInBytes() { return texture.objectSize(); }
 
     RenderState& renderState;
 
@@ -124,8 +124,8 @@
 
         Entry(OffscreenBuffer* layer)
                 : layer(layer)
-                , width(layer->texture.width)
-                , height(layer->texture.height) {
+                , width(layer->texture.width())
+                , height(layer->texture.height()) {
         }
 
         static int compare(const Entry& lhs, const Entry& rhs);
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 4fa8200..e71d6ee 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -13,12 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <GpuMemoryTracker.h>
 #include "renderstate/RenderState.h"
 
 #include "renderthread/CanvasContext.h"
 #include "renderthread/EglManager.h"
 #include "utils/GLUtils.h"
-
 #include <algorithm>
 
 namespace android {
@@ -40,6 +40,8 @@
 void RenderState::onGLContextCreated() {
     LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil,
             "State object lifecycle not managed correctly");
+    GpuMemoryTracker::onGLContextCreated();
+
     mBlend = new Blend();
     mMeshState = new MeshState();
     mScissor = new Scissor();
@@ -106,6 +108,8 @@
     mScissor = nullptr;
     delete mStencil;
     mStencil = nullptr;
+
+    GpuMemoryTracker::onGLContextDestroyed();
 }
 
 void RenderState::flush(Caches::FlushMode mode) {
@@ -205,17 +209,6 @@
     }
 }
 
-void RenderState::requireGLContext() {
-    assertOnGLThread();
-    LOG_ALWAYS_FATAL_IF(!mRenderThread.eglManager().hasEglContext(),
-            "No GL context!");
-}
-
-void RenderState::assertOnGLThread() {
-    pthread_t curr = pthread_self();
-    LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!");
-}
-
 class DecStrongTask : public renderthread::RenderTask {
 public:
     DecStrongTask(VirtualLightRefBase* object) : mObject(object) {}
@@ -231,7 +224,11 @@
 };
 
 void RenderState::postDecStrong(VirtualLightRefBase* object) {
-    mRenderThread.queue(new DecStrongTask(object));
+    if (pthread_equal(mThreadId, pthread_self())) {
+        object->decStrong(nullptr);
+    } else {
+        mRenderThread.queue(new DecStrongTask(object));
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -244,6 +241,8 @@
     const Glop::Mesh::Indices& indices = mesh.indices;
     const Glop::Fill& fill = glop.fill;
 
+    GL_CHECKPOINT();
+
     // ---------------------------------------------
     // ---------- Program + uniform setup ----------
     // ---------------------------------------------
@@ -287,6 +286,8 @@
                 roundedOutRadius);
     }
 
+    GL_CHECKPOINT();
+
     // --------------------------------
     // ---------- Mesh setup ----------
     // --------------------------------
@@ -310,7 +311,7 @@
             texture.texture->setFilter(texture.filter, true, false, texture.target);
         }
 
-        mCaches->textureState().bindTexture(texture.target, texture.texture->id);
+        mCaches->textureState().bindTexture(texture.target, texture.texture->id());
         meshState().enableTexCoordsVertexArray();
         meshState().bindTexCoordsVertexPointer(force, vertices.texCoord, vertices.stride);
 
@@ -338,11 +339,15 @@
     // Shader uniforms
     SkiaShader::apply(*mCaches, fill.skiaShaderData);
 
+    GL_CHECKPOINT();
+
     // ------------------------------------
     // ---------- GL state setup ----------
     // ------------------------------------
     blend().setFactors(glop.blend.src, glop.blend.dst);
 
+    GL_CHECKPOINT();
+
     // ------------------------------------
     // ---------- Actual drawing ----------
     // ------------------------------------
@@ -371,6 +376,8 @@
         glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount);
     }
 
+    GL_CHECKPOINT();
+
     // -----------------------------------
     // ---------- Mesh teardown ----------
     // -----------------------------------
@@ -380,6 +387,8 @@
     if (vertices.attribFlags & VertexAttribFlags::Color) {
         glDisableVertexAttribArray(colorLocation);
     }
+
+    GL_CHECKPOINT();
 }
 
 void RenderState::dump() {
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index dcd5ea6..e5d3e79 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -86,8 +86,6 @@
         mRegisteredContexts.erase(context);
     }
 
-    void requireGLContext();
-
     // TODO: This system is a little clunky feeling, this could use some
     // more thinking...
     void postDecStrong(VirtualLightRefBase* object);
@@ -107,7 +105,6 @@
 private:
     void interruptForFunctorInvoke();
     void resumeFromFunctorInvoke();
-    void assertOnGLThread();
 
     RenderState(renderthread::RenderThread& thread);
     ~RenderState();
diff --git a/libs/hwui/renderstate/TextureState.cpp b/libs/hwui/renderstate/TextureState.cpp
index 1f50f71..78b8eda 100644
--- a/libs/hwui/renderstate/TextureState.cpp
+++ b/libs/hwui/renderstate/TextureState.cpp
@@ -34,134 +34,6 @@
     GL_TEXTURE3
 };
 
-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) {
-        if (useStride) {
-            glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
-        }
-
-        if (resize) {
-            glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data);
-        } else {
-            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data);
-        }
-
-        if (useStride) {
-            glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-        }
-    } else {
-        //  With OpenGL ES 2.0 we need to copy the bitmap in a temporary buffer
-        //  if the stride doesn't match the width
-
-        GLvoid * temp = (GLvoid *) malloc(width * height * bpp);
-        if (!temp) return;
-
-        uint8_t * pDst = (uint8_t *)temp;
-        uint8_t * pSrc = (uint8_t *)data;
-        for (GLsizei i = 0; i < height; i++) {
-            memcpy(pDst, pSrc, width * bpp);
-            pDst += width * bpp;
-            pSrc += stride * bpp;
-        }
-
-        if (resize) {
-            glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, temp);
-        } else {
-            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, temp);
-        }
-
-        free(temp);
-    }
-}
-
-static void uploadSkBitmapToTexture(const SkBitmap& bitmap,
-        bool resize, GLenum format, GLenum type) {
-    uploadToTexture(resize, format, type, bitmap.rowBytesAsPixels(), bitmap.bytesPerPixel(),
-            bitmap.width(), bitmap.height(), bitmap.getPixels());
-}
-
-void TextureState::generateTexture(const SkBitmap* bitmap, Texture* texture, bool regenerate) {
-    SkAutoLockPixels alp(*bitmap);
-
-    if (!bitmap->readyToDraw()) {
-        ALOGE("Cannot generate texture from bitmap");
-        return;
-    }
-
-    ATRACE_FORMAT("Upload %ux%u Texture", bitmap->width(), bitmap->height());
-
-    // We could also enable mipmapping if both bitmap dimensions are powers
-    // of 2 but we'd have to deal with size changes. Let's keep this simple
-    const bool canMipMap = Caches::getInstance().extensions().hasNPot();
-
-    // If the texture had mipmap enabled but not anymore,
-    // force a glTexImage2D to discard the mipmap levels
-    const bool resize = !regenerate || bitmap->width() != int(texture->width) ||
-            bitmap->height() != int(texture->height) ||
-            (regenerate && canMipMap && texture->mipMap && !bitmap->hasHardwareMipMap());
-
-    if (!regenerate) {
-        glGenTextures(1, &texture->id);
-    }
-
-    texture->generation = bitmap->getGenerationID();
-    texture->width = bitmap->width();
-    texture->height = bitmap->height();
-
-    bindTexture(texture->id);
-
-    switch (bitmap->colorType()) {
-    case kAlpha_8_SkColorType:
-        uploadSkBitmapToTexture(*bitmap, resize, GL_ALPHA, GL_UNSIGNED_BYTE);
-        texture->blend = true;
-        break;
-    case kRGB_565_SkColorType:
-        uploadSkBitmapToTexture(*bitmap, resize, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
-        texture->blend = false;
-        break;
-    case kN32_SkColorType:
-        uploadSkBitmapToTexture(*bitmap, resize, GL_RGBA, GL_UNSIGNED_BYTE);
-        // Do this after calling getPixels() to make sure Skia's deferred
-        // decoding happened
-        texture->blend = !bitmap->isOpaque();
-        break;
-    case kARGB_4444_SkColorType:
-    case kIndex_8_SkColorType: {
-        SkBitmap rgbaBitmap;
-        rgbaBitmap.allocPixels(SkImageInfo::MakeN32(texture->width, texture->height,
-                bitmap->alphaType()));
-        rgbaBitmap.eraseColor(0);
-
-        SkCanvas canvas(rgbaBitmap);
-        canvas.drawBitmap(*bitmap, 0.0f, 0.0f, nullptr);
-
-        uploadSkBitmapToTexture(rgbaBitmap, resize, GL_RGBA, GL_UNSIGNED_BYTE);
-        texture->blend = !bitmap->isOpaque();
-        break;
-    }
-    default:
-        ALOGW("Unsupported bitmap colorType: %d", bitmap->colorType());
-        break;
-    }
-
-    if (canMipMap) {
-        texture->mipMap = bitmap->hasHardwareMipMap();
-        if (texture->mipMap) {
-            glGenerateMipmap(GL_TEXTURE_2D);
-        }
-    }
-
-    if (!regenerate) {
-        texture->setFilter(GL_NEAREST);
-        texture->setWrap(GL_CLAMP_TO_EDGE);
-    }
-}
-
 TextureState::TextureState()
         : mTextureUnit(0) {
     glActiveTexture(kTextureUnits[0]);
@@ -171,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/renderstate/TextureState.h b/libs/hwui/renderstate/TextureState.h
index 3a2b85a..ec94d7e 100644
--- a/libs/hwui/renderstate/TextureState.h
+++ b/libs/hwui/renderstate/TextureState.h
@@ -76,13 +76,6 @@
      */
     void unbindTexture(GLuint texture);
 
-    /**
-     * Generates the texture from a bitmap into the specified texture structure.
-     *
-     * @param regenerate If true, the bitmap data is reuploaded into the texture, but
-     *        no new texture is generated.
-     */
-    void generateTexture(const SkBitmap* bitmap, Texture* texture, bool regenerate);
 private:
     // total number of texture units available for use
     static const int kTextureUnitsCount = 4;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 644f356..6f8d627 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <GpuMemoryTracker.h>
 #include "CanvasContext.h"
 
 #include "AnimationContext.h"
@@ -28,6 +29,7 @@
 #include "renderstate/RenderState.h"
 #include "renderstate/Stencil.h"
 #include "protos/hwui.pb.h"
+#include "utils/GLUtils.h"
 #include "utils/TimeUtils.h"
 
 #if HWUI_NEW_OPS
@@ -212,10 +214,13 @@
         // node(s) are non client / filler nodes.
         info.mode = (node.get() == target ? TreeInfo::MODE_FULL : TreeInfo::MODE_RT_ONLY);
         node->prepareTree(info);
+        GL_CHECKPOINT();
     }
     mAnimationContext->runRemainingAnimations(info);
+    GL_CHECKPOINT();
 
     freePrefetechedLayers();
+    GL_CHECKPOINT();
 
     if (CC_UNLIKELY(!mNativeWindow.get())) {
         mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
@@ -462,6 +467,9 @@
 
     bool drew = mCanvas->finish();
 #endif
+
+    GL_CHECKPOINT();
+
     // Even if we decided to cancel the frame, from the perspective of jank
     // metrics the frame was swapped at this point
     mCurrentFrameInfo->markSwapBuffers();
@@ -497,6 +505,8 @@
 
     mJankTracker.addFrame(*mCurrentFrameInfo);
     mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo);
+
+    GpuMemoryTracker::onFrameCompleted();
 }
 
 // Called by choreographer to do an RT-driven animation
@@ -512,11 +522,11 @@
 void CanvasContext::prepareAndDraw(RenderNode* node) {
     ATRACE_CALL();
 
+    nsecs_t vsync = mRenderThread.timeLord().computeFrameTimeNanos();
     int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE];
     UiFrameInfoBuilder(frameInfo)
         .addFlag(FrameInfoFlags::RTAnimation)
-        .setVsync(mRenderThread.timeLord().computeFrameTimeNanos(),
-                mRenderThread.timeLord().latestVsync());
+        .setVsync(vsync, vsync);
 
     TreeInfo info(TreeInfo::MODE_RT_ONLY, *this);
     prepareTree(info, frameInfo, systemTime(CLOCK_MONOTONIC), node);
@@ -578,7 +588,7 @@
     node->setPropertyFieldsDirty(RenderNode::GENERIC);
 
 #if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("unsupported");
+    // TODO: support buildLayer
 #else
     mCanvas->markLayersAsBuildLayers();
     mCanvas->flushLayerUpdates();
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 43282c9..db2a2c8 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -384,6 +384,12 @@
     postAndWait(task);
 }
 
+void RenderProxy::staticFence() {
+    SETUP_TASK(fence);
+    UNUSED(args);
+    staticPostAndWait(task);
+}
+
 CREATE_BRIDGE1(stopDrawing, CanvasContext* context) {
     args->context->stopDrawing();
     return nullptr;
@@ -450,6 +456,11 @@
     } else {
         fprintf(file, "\nNo caches instance.\n");
     }
+#if HWUI_NEW_OPS
+    fprintf(file, "\nPipeline=FrameBuilder\n");
+#else
+    fprintf(file, "\nPipeline=OpenGLRenderer\n");
+#endif
     fflush(file);
     return nullptr;
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 1d30eb8..0f91b2a 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -93,6 +93,7 @@
     ANDROID_API static void overrideProperty(const char* name, const char* value);
 
     ANDROID_API void fence();
+    ANDROID_API static void staticFence();
     ANDROID_API void stopDrawing();
     ANDROID_API void notifyFramePending();
 
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 624f3bd..5ed7aa4 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -19,6 +19,9 @@
 #include "DeferredLayerUpdater.h"
 #include "LayerRenderer.h"
 
+#include <unistd.h>
+#include <signal.h>
+
 namespace android {
 namespace uirenderer {
 
@@ -121,5 +124,37 @@
     canvas->drawTextOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint);
 }
 
+static void defaultCrashHandler() {
+    fprintf(stderr, "RenderThread crashed!");
+}
+
+static std::function<void()> gCrashHandler = defaultCrashHandler;
+static sighandler_t gPreviousSignalHandler;
+
+static void signalHandler(int sig) {
+    gCrashHandler();
+    if (gPreviousSignalHandler) {
+        gPreviousSignalHandler(sig);
+    }
+}
+
+void TestUtils::setRenderThreadCrashHandler(std::function<void()> crashHandler) {
+    gCrashHandler = crashHandler;
+}
+
+void TestUtils::TestTask::run() {
+    gPreviousSignalHandler = signal(SIGABRT, signalHandler);
+
+    // RenderState only valid once RenderThread is running, so queried here
+    RenderState& renderState = renderthread::RenderThread::getInstance().renderState();
+
+    renderState.onGLContextCreated();
+    rtCallback(renderthread::RenderThread::getInstance());
+    renderState.onGLContextDestroyed();
+
+    // Restore the previous signal handler
+    signal(SIGABRT, gPreviousSignalHandler);
+}
+
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index edde31e..ae08142 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -171,21 +171,23 @@
         syncHierarchyPropertiesAndDisplayListImpl(node.get());
     }
 
+    static std::vector<sp<RenderNode>> createSyncedNodeList(sp<RenderNode>& node) {
+        TestUtils::syncHierarchyPropertiesAndDisplayList(node);
+        std::vector<sp<RenderNode>> vec;
+        vec.emplace_back(node);
+        return vec;
+    }
+
     typedef std::function<void(renderthread::RenderThread& thread)> RtCallback;
 
+    static void setRenderThreadCrashHandler(std::function<void()> crashHandler);
+
     class TestTask : public renderthread::RenderTask {
     public:
         TestTask(RtCallback rtCallback)
                 : rtCallback(rtCallback) {}
         virtual ~TestTask() {}
-        virtual void run() override {
-            // RenderState only valid once RenderThread is running, so queried here
-            RenderState& renderState = renderthread::RenderThread::getInstance().renderState();
-
-            renderState.onGLContextCreated();
-            rtCallback(renderthread::RenderThread::getInstance());
-            renderState.onGLContextDestroyed();
-        };
+        virtual void run() override;
         RtCallback rtCallback;
     };
 
@@ -197,6 +199,10 @@
         renderthread::RenderThread::getInstance().queueAndWait(&task);
     }
 
+    static bool isRenderThreadRunning() {
+        return renderthread::RenderThread::hasInstance();
+    }
+
     static SkColor interpolateColor(float fraction, SkColor start, SkColor end);
 
     static void drawTextToCanvas(TestCanvas* canvas, const char* text,
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index 1616a95..02a3950 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -25,6 +25,7 @@
 #include <unistd.h>
 #include <unordered_map>
 #include <vector>
+#include <pthread.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/libs/hwui/tests/unit/CrashHandlerInjector.cpp b/libs/hwui/tests/unit/CrashHandlerInjector.cpp
new file mode 100644
index 0000000..b1c678d
--- /dev/null
+++ b/libs/hwui/tests/unit/CrashHandlerInjector.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tests/common/TestUtils.h"
+
+#include <gtest/gtest.h>
+#include <cstdio>
+
+using namespace android::uirenderer;
+
+static void gunitCrashHandler() {
+    auto testinfo = ::testing::UnitTest::GetInstance()->current_test_info();
+    printf("[  FAILED  ] %s.%s\n", testinfo->test_case_name(),
+            testinfo->name());
+    printf("[  FATAL!  ] RenderThread crashed, aborting tests!\n");
+    fflush(stdout);
+}
+
+static void hookError() {
+    TestUtils::setRenderThreadCrashHandler(gunitCrashHandler);
+}
+
+class HookErrorInit {
+public:
+    HookErrorInit() { hookError(); }
+};
+
+static HookErrorInit sInit;
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index bded50a..b51bd2f 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -32,13 +32,6 @@
 const LayerUpdateQueue sEmptyLayerUpdateQueue;
 const Vector3 sLightCenter = {100, 100, 100};
 
-static std::vector<sp<RenderNode>> createSyncedNodeList(sp<RenderNode>& node) {
-    TestUtils::syncHierarchyPropertiesAndDisplayList(node);
-    std::vector<sp<RenderNode>> vec;
-    vec.emplace_back(node);
-    return vec;
-}
-
 /**
  * Virtual class implemented by each test to redirect static operation / state transitions to
  * virtual methods.
@@ -139,7 +132,7 @@
         canvas.drawBitmap(bitmap, 10, 10, nullptr);
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SimpleTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex()); // 2 ops + start + end
@@ -165,7 +158,7 @@
         canvas.drawPoint(50, 50, strokedPaint);
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SimpleStrokeTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(1, renderer.getIndex());
@@ -180,7 +173,7 @@
         canvas.restore();
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
 
     FailRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
@@ -215,7 +208,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SimpleBatchingTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2 * LOOPS, renderer.getIndex())
@@ -256,7 +249,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     ClippedMergingTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex());
@@ -284,7 +277,7 @@
         TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 100); // not clipped
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     TextMergingTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2, renderer.getIndex()) << "Expect 2 ops";
@@ -315,7 +308,7 @@
         }
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 2000), 200, 2000,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     TextStrikethroughTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2 * LOOPS, renderer.getIndex())
@@ -349,7 +342,7 @@
         canvas.restore();
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     TextureLayerTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(1, renderer.getIndex());
@@ -394,7 +387,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(parent), sLightCenter);
+            TestUtils::createSyncedNodeList(parent), sLightCenter);
     RenderNodeTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
 }
@@ -418,7 +411,7 @@
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue,
             SkRect::MakeLTRB(10, 20, 30, 40), // clip to small area, should see in receiver
-            200, 200, createSyncedNodeList(node), sLightCenter);
+            200, 200, TestUtils::createSyncedNodeList(node), sLightCenter);
     ClippedTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
 }
@@ -460,7 +453,7 @@
         canvas.restore();
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SaveLayerSimpleTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex());
@@ -532,7 +525,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(800, 800), 800, 800,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SaveLayerNestedTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(10, renderer.getIndex());
@@ -552,7 +545,7 @@
         canvas.restore();
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
 
     FailRenderer renderer;
     // should see no ops, even within the layer, since the layer should be rejected
@@ -590,12 +583,12 @@
 
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 10, 190, 190, 128, SkCanvas::kMatrixClip_SaveFlag);
+        canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SkCanvas::SaveFlags)(0));
         canvas.drawRect(0, 0, 200, 200, SkPaint());
         canvas.restore();
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SaveLayerUnclippedSimpleTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex());
@@ -649,7 +642,7 @@
         canvas.restoreToCount(restoreTo);
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SaveLayerUnclippedMergedClearsTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(10, renderer.getIndex())
@@ -711,7 +704,7 @@
         canvas.restore();
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(600, 600), 600, 600,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     SaveLayerUnclippedComplexTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(12, renderer.getIndex());
@@ -762,7 +755,7 @@
     OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
     *layerHandle = &layer;
 
-    auto syncedNodeList = createSyncedNodeList(node);
+    auto syncedNodeList = TestUtils::createSyncedNodeList(node);
 
     // only enqueue partial damage
     LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
@@ -863,7 +856,7 @@
     OffscreenBuffer parentLayer(renderThread.renderState(), Caches::getInstance(), 200, 200);
     *(parent->getLayerHandle()) = &parentLayer;
 
-    auto syncedList = createSyncedNodeList(parent);
+    auto syncedList = TestUtils::createSyncedNodeList(parent);
 
     LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
     layerUpdateQueue.enqueueLayerWithDamage(child.get(), Rect(100, 100));
@@ -919,7 +912,7 @@
         drawOrderedNode(&canvas, 9, -10.0f); // in reorder=false at this point, so played inorder
     });
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100,
-            createSyncedNodeList(parent), sLightCenter);
+            TestUtils::createSyncedNodeList(parent), sLightCenter);
     ZReorderTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(10, renderer.getIndex());
@@ -1002,7 +995,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100,
-            createSyncedNodeList(parent), sLightCenter);
+            TestUtils::createSyncedNodeList(parent), sLightCenter);
     ProjectionReorderTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(3, renderer.getIndex());
@@ -1045,7 +1038,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(parent), sLightCenter);
+            TestUtils::createSyncedNodeList(parent), sLightCenter);
     ShadowTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2, renderer.getIndex());
@@ -1086,7 +1079,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(parent), (Vector3) { 100, 100, 100 });
+            TestUtils::createSyncedNodeList(parent), (Vector3) { 100, 100, 100 });
     ShadowSaveLayerTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(5, renderer.getIndex());
@@ -1132,7 +1125,7 @@
     layer.setWindowTransform(windowTransform);
     *layerHandle = &layer;
 
-    auto syncedList = createSyncedNodeList(parent);
+    auto syncedList = TestUtils::createSyncedNodeList(parent);
     LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
     layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(100, 100));
     FrameBuilder frameBuilder(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
@@ -1165,7 +1158,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
-            createSyncedNodeList(parent), sLightCenter);
+            TestUtils::createSyncedNodeList(parent), sLightCenter);
     ShadowLayeringTestRenderer renderer;
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex());
@@ -1193,7 +1186,7 @@
     });
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 200, 200,
-            createSyncedNodeList(node), sLightCenter);
+            TestUtils::createSyncedNodeList(node), sLightCenter);
     PropertyTestRenderer renderer(opValidateCallback);
     frameBuilder.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(1, renderer.getIndex()) << "Should have seen one op";
@@ -1332,7 +1325,7 @@
         paint.setColor(SK_ColorWHITE);
         canvas.drawRect(0, 0, 10000, 10000, paint);
     });
-    auto nodes = createSyncedNodeList(node); // sync before querying height
+    auto nodes = TestUtils::createSyncedNodeList(node); // sync before querying height
 
     FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, nodes, sLightCenter);
     SaveLayerAlphaClipTestRenderer renderer(outObservedData);
diff --git a/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
new file mode 100644
index 0000000..aa1dcb2
--- /dev/null
+++ b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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 <gtest/gtest.h>
+#include <GpuMemoryTracker.h>
+
+#include "renderthread/EglManager.h"
+#include "renderthread/RenderThread.h"
+#include "tests/common/TestUtils.h"
+
+#include <utils/StrongPointer.h>
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+
+class TestGPUObject : public GpuMemoryTracker {
+public:
+    TestGPUObject() : GpuMemoryTracker(GpuObjectType::Texture) {}
+
+    void changeSize(int newSize) {
+        notifySizeChanged(newSize);
+    }
+};
+
+// Other tests may have created a renderthread and EGL context.
+// This will destroy the EGLContext on RenderThread if it exists so that the
+// current thread can spoof being a GPU thread
+static void destroyEglContext() {
+    if (TestUtils::isRenderThreadRunning()) {
+        TestUtils::runOnRenderThread([](RenderThread& thread) {
+            thread.eglManager().destroy();
+        });
+    }
+}
+
+TEST(GpuMemoryTracker, sizeCheck) {
+    destroyEglContext();
+
+    GpuMemoryTracker::onGLContextCreated();
+    ASSERT_EQ(0, GpuMemoryTracker::getTotalSize(GpuObjectType::Texture));
+    ASSERT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture));
+    {
+        TestGPUObject myObj;
+        ASSERT_EQ(1, GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture));
+        myObj.changeSize(500);
+        ASSERT_EQ(500, GpuMemoryTracker::getTotalSize(GpuObjectType::Texture));
+        myObj.changeSize(1000);
+        ASSERT_EQ(1000, GpuMemoryTracker::getTotalSize(GpuObjectType::Texture));
+        myObj.changeSize(300);
+        ASSERT_EQ(300, GpuMemoryTracker::getTotalSize(GpuObjectType::Texture));
+    }
+    ASSERT_EQ(0, GpuMemoryTracker::getTotalSize(GpuObjectType::Texture));
+    ASSERT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture));
+    GpuMemoryTracker::onGLContextDestroyed();
+}
diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp
new file mode 100644
index 0000000..41e44fc
--- /dev/null
+++ b/libs/hwui/tests/unit/LeakCheckTests.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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 "BakedOpRenderer.h"
+#include "BakedOpDispatcher.h"
+#include "FrameBuilder.h"
+#include "LayerUpdateQueue.h"
+#include "RecordingCanvas.h"
+#include "tests/common/TestUtils.h"
+
+#include <gtest/gtest.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+const LayerUpdateQueue sEmptyLayerUpdateQueue;
+const Vector3 sLightCenter = {100, 100, 100};
+
+RENDERTHREAD_TEST(LeakCheck, saveLayerUnclipped_simple) {
+    auto node = TestUtils::createNode(0, 0, 200, 200,
+            [](RenderProperties& props, RecordingCanvas& canvas) {
+        canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SkCanvas::SaveFlags)(0));
+        canvas.drawRect(0, 0, 200, 200, SkPaint());
+        canvas.restore();
+    });
+    BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128};
+    RenderState& renderState = renderThread.renderState();
+    Caches& caches = Caches::getInstance();
+
+    FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            TestUtils::createSyncedNodeList(node), sLightCenter);
+    BakedOpRenderer renderer(caches, renderState, true, lightInfo);
+    frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
+}
diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
index e96e9ba..2fd8795 100644
--- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
@@ -36,8 +36,8 @@
         EXPECT_EQ(49u, layer.viewportWidth);
         EXPECT_EQ(149u, layer.viewportHeight);
 
-        EXPECT_EQ(64u, layer.texture.width);
-        EXPECT_EQ(192u, layer.texture.height);
+        EXPECT_EQ(64u, layer.texture.width());
+        EXPECT_EQ(192u, layer.texture.height());
 
         EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes());
     });
@@ -100,8 +100,8 @@
         ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
         EXPECT_EQ(60u, layer->viewportWidth);
         EXPECT_EQ(55u, layer->viewportHeight);
-        EXPECT_EQ(64u, layer->texture.width);
-        EXPECT_EQ(64u, layer->texture.height);
+        EXPECT_EQ(64u, layer->texture.width());
+        EXPECT_EQ(64u, layer->texture.height());
 
         // resized to use different object in pool
         auto layer2 = pool.get(thread.renderState(), 128u, 128u);
@@ -110,12 +110,14 @@
         ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
         EXPECT_EQ(120u, layer2->viewportWidth);
         EXPECT_EQ(125u, layer2->viewportHeight);
-        EXPECT_EQ(128u, layer2->texture.width);
-        EXPECT_EQ(128u, layer2->texture.height);
+        EXPECT_EQ(128u, layer2->texture.width());
+        EXPECT_EQ(128u, layer2->texture.height());
 
         // original allocation now only thing in pool
         EXPECT_EQ(1u, pool.getCount());
         EXPECT_EQ(layer->getSizeInBytes(), pool.getSize());
+
+        pool.putOrDelete(layer2);
     });
 }
 
diff --git a/libs/hwui/tests/unit/StringUtilsTests.cpp b/libs/hwui/tests/unit/StringUtilsTests.cpp
index 6b2e265..b60e96c 100644
--- a/libs/hwui/tests/unit/StringUtilsTests.cpp
+++ b/libs/hwui/tests/unit/StringUtilsTests.cpp
@@ -36,3 +36,18 @@
     EXPECT_TRUE(collection.has("GL_ext1"));
     EXPECT_FALSE(collection.has("GL_ext")); // string present, but not in list
 }
+
+TEST(StringUtils, sizePrinter) {
+    std::stringstream os;
+    os << SizePrinter{500};
+    EXPECT_EQ("500.00B", os.str());
+    os.str("");
+    os << SizePrinter{46080};
+    EXPECT_EQ("45.00KiB", os.str());
+    os.str("");
+    os << SizePrinter{5 * 1024 * 1024 + 520 * 1024};
+    EXPECT_EQ("5.51MiB", os.str());
+    os.str("");
+    os << SizePrinter{2147483647};
+    EXPECT_EQ("2048.00MiB", os.str());
+}
diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h
index 7020461..85a10f9 100644
--- a/libs/hwui/utils/GLUtils.h
+++ b/libs/hwui/utils/GLUtils.h
@@ -16,9 +16,20 @@
 #ifndef GLUTILS_H
 #define GLUTILS_H
 
+#include "Debug.h"
+
+#include <cutils/log.h>
+
 namespace android {
 namespace uirenderer {
 
+#if DEBUG_OPENGL
+#define GL_CHECKPOINT() LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(),\
+        "GL errors! %s:%d", __FILE__, __LINE__)
+#else
+#define GL_CHECKPOINT()
+#endif
+
 class GLUtils {
 public:
     /**
diff --git a/libs/hwui/utils/StringUtils.h b/libs/hwui/utils/StringUtils.h
index 055869f..05a3d59 100644
--- a/libs/hwui/utils/StringUtils.h
+++ b/libs/hwui/utils/StringUtils.h
@@ -18,6 +18,8 @@
 
 #include <string>
 #include <unordered_set>
+#include <ostream>
+#include <iomanip>
 
 namespace android {
 namespace uirenderer {
@@ -34,6 +36,21 @@
     static unordered_string_set split(const char* spacedList);
 };
 
+struct SizePrinter {
+    int bytes;
+    friend std::ostream& operator<<(std::ostream& stream, const SizePrinter& d) {
+        static const char* SUFFIXES[] = {"B", "KiB", "MiB"};
+        size_t suffix = 0;
+        double temp = d.bytes;
+        while (temp > 1000 && suffix < 2) {
+            temp /= 1024.0;
+            suffix++;
+        }
+        stream << std::fixed << std::setprecision(2) << temp << SUFFIXES[suffix];
+        return stream;
+    }
+};
+
 } /* namespace uirenderer */
 } /* namespace android */
 
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index 05b4a72..dcc4946 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -18,6 +18,7 @@
 #include "AnimationContext.h"
 #include "DisplayListCanvas.h"
 #include "IContextFactory.h"
+#include "RecordingCanvas.h"
 #include "RenderNode.h"
 #include "SkTypes.h"
 #include "gui/BufferQueue.h"
@@ -88,9 +89,11 @@
         mProxy->setup(mSize.width(), mSize.height(), 800.0f,
                              255 * 0.075f, 255 * 0.15f);
         mProxy->setLightCenter(lightVector);
-        mCanvas.reset(new
-            android::uirenderer::DisplayListCanvas(mSize.width(),
-                                                   mSize.height()));
+#if HWUI_NEW_OPS
+        mCanvas.reset(new android::uirenderer::RecordingCanvas(mSize.width(), mSize.height()));
+#else
+        mCanvas.reset(new android::uirenderer::DisplayListCanvas(mSize.width(), mSize.height()));
+#endif
     }
 
     SkCanvas* prepareToDraw() {
@@ -168,7 +171,11 @@
 
     std::unique_ptr<android::uirenderer::RenderNode> mRootNode;
     std::unique_ptr<android::uirenderer::renderthread::RenderProxy> mProxy;
+#if HWUI_NEW_OPS
+    std::unique_ptr<android::uirenderer::RecordingCanvas> mCanvas;
+#else
     std::unique_ptr<android::uirenderer::DisplayListCanvas> mCanvas;
+#endif
     android::sp<android::IGraphicBufferProducer> mProducer;
     android::sp<android::IGraphicBufferConsumer> mConsumer;
     android::sp<android::CpuConsumer> mCpuConsumer;
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index e92f294..efae628 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -223,10 +223,19 @@
     @SystemApi
     public final static int FLAG_BYPASS_MUTE = 0x1 << 7;
 
+    /**
+     * @hide
+     * Flag requesting a low latency path.
+     * When using this flag, the sample rate must match the native sample rate
+     * of the device. Effects processing is also unavailable.
+     */
+    public final static int FLAG_LOW_LATENCY = 0x1 << 8;
+
     private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO |
             FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY |
-            FLAG_BYPASS_MUTE;
-    private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC;
+            FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY;
+    private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
+            FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
 
     private int mUsage = USAGE_UNKNOWN;
     private int mContentType = CONTENT_TYPE_UNKNOWN;
@@ -433,7 +442,8 @@
 
         /**
          * Sets the combination of flags.
-         * @param flags the {@link AudioAttributes#FLAG_AUDIBILITY_ENFORCED} flag.
+         * @param flags a combination of {@link AudioAttributes#FLAG_AUDIBILITY_ENFORCED},
+         *    {@link AudioAttributes#FLAG_HW_AV_SYNC}.
          * @return the same Builder instance.
          */
         public Builder setFlags(int flags) {
@@ -520,8 +530,9 @@
          * instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}.
          * @param preset one of {@link MediaRecorder.AudioSource#DEFAULT},
          *     {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER},
-         *     {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} or
-         *     {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
+         *     {@link MediaRecorder.AudioSource#VOICE_RECOGNITION},
+         *     {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION} or
+         *     {@link MediaRecorder.AudioSource#UNPROCESSED}
          * @return the same Builder instance.
          */
         @SystemApi
@@ -532,6 +543,7 @@
                 case MediaRecorder.AudioSource.CAMCORDER:
                 case MediaRecorder.AudioSource.VOICE_RECOGNITION:
                 case MediaRecorder.AudioSource.VOICE_COMMUNICATION:
+                case MediaRecorder.AudioSource.UNPROCESSED:
                     mSource = preset;
                     break;
                 default:
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ea1690f..5ad6b08 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3305,12 +3305,19 @@
             "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
 
     /**
+     * Used as a key for {@link #getProperty} to determine if the unprocessed audio source is
+     * available and supported with the expected frequency range and level response.
+     */
+    public static final String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED =
+            "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
+    /**
      * Returns the value of the property with the specified key.
      * @param key One of the strings corresponding to a property key: either
      *            {@link #PROPERTY_OUTPUT_SAMPLE_RATE},
      *            {@link #PROPERTY_OUTPUT_FRAMES_PER_BUFFER},
-     *            {@link #PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND}, or
-     *            {@link #PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND}.
+     *            {@link #PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND},
+     *            {@link #PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND}, or
+     *            {@link #PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED}.
      * @return A string representing the associated value for that property key,
      *         or null if there is no value for that key.
      */
@@ -3329,6 +3336,9 @@
         } else if (PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND.equals(key)) {
             return String.valueOf(getContext().getResources().getBoolean(
                     com.android.internal.R.bool.config_supportSpeakerNearUltrasound));
+        } else if (PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED.equals(key)) {
+            return String.valueOf(getContext().getResources().getBoolean(
+                    com.android.internal.R.bool.config_supportAudioSourceUnprocessed));
         } else {
             // null or unknown key
             return null;
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 974b62e..7c21893 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -51,7 +51,7 @@
  * been read yet. Data should be read from the audio hardware in chunks of sizes inferior to
  * the total recording buffer size.
  */
-public class AudioRecord
+public class AudioRecord implements AudioRouting
 {
     //---------------------------------------------------------
     // Constants
@@ -392,6 +392,20 @@
     }
 
     /**
+     * A constructor which explicitly connects a Native (C++) AudioRecord. For use by
+     * the AudioRecordRoutingProxy subclass.
+     * @param nativeRecordInJavaObj A C/C++ pointer to a native AudioRecord
+     * (associated with an OpenSL ES recorder).
+     */
+    /*package*/ AudioRecord(long nativeRecordInJavaObj) {
+        mNativeRecorderInJavaObj = nativeRecordInJavaObj;
+
+        // other initialization here...
+
+        mState = STATE_INITIALIZED;
+    }
+
+    /**
      * Builder class for {@link AudioRecord} objects.
      * Use this class to configure and create an <code>AudioRecord</code> instance. By setting the
      * recording source and audio format parameters, you indicate which of
@@ -1221,23 +1235,6 @@
         return native_set_marker_pos(markerInFrames);
     }
 
-
-    //--------------------------------------------------------------------------
-    // (Re)Routing Info
-    //--------------------
-    /**
-     * Defines the interface by which applications can receive notifications of routing
-     * changes for the associated {@link AudioRecord}.
-     */
-    public interface OnRoutingChangedListener {
-        /**
-         * Called when the routing of an AudioRecord changes from either and explicit or
-         * policy rerouting. Use {@link #getRoutedDevice()} to retrieve the newly routed-from
-         * device.
-         */
-        public void onRoutingChanged(AudioRecord audioRecord);
-    }
-
     /**
      * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioRecord.
      * Note: The query is only valid if the AudioRecord is currently recording. If it is not,
@@ -1258,6 +1255,89 @@
         return null;
     }
 
+    /*
+     * Call BEFORE adding a routing callback handler.
+     */
+    private void testEnableNativeRoutingCallbacks() {
+        if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
+            native_enableDeviceCallback();
+        }
+    }
+
+    /*
+     * Call AFTER removing a routing callback handler.
+     */
+    private void testDisableNativeRoutingCallbacks() {
+        if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
+            native_disableDeviceCallback();
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // >= "N" (Re)Routing Info
+    //--------------------
+    /**
+     * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
+     * {@link AudioRecord#addOnRoutingListener(AudioRouting.OnRoutingChangedListener,
+     *      android.os.Handler)}
+     * by an app to receive (re)routing notifications.
+     */
+    private ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>
+    mNewRoutingChangeListeners =
+        new ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>();
+
+    /**
+     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of
+     * routing changes on this AudioRecord.
+     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+     * notifications of rerouting events.
+     * @param handler  Specifies 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 addOnRoutingListener(AudioRouting.OnRoutingChangedListener listener,
+            android.os.Handler handler) {
+        if (listener != null && !mNewRoutingChangeListeners.containsKey(listener)) {
+            synchronized (mNewRoutingChangeListeners) {
+                testEnableNativeRoutingCallbacks();
+                mNewRoutingChangeListeners.put(
+                    listener, new NativeNewRoutingEventHandlerDelegate(this, listener,
+                            handler != null ? handler : new Handler(mInitializationLooper)));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+    * to receive rerouting notifications.
+    * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+    * to remove.
+    */
+    public void removeOnRoutingListener(AudioRouting.OnRoutingChangedListener listener) {
+        synchronized (mNewRoutingChangeListeners) {
+            if (mNewRoutingChangeListeners.containsKey(listener)) {
+                mNewRoutingChangeListeners.remove(listener);
+                testDisableNativeRoutingCallbacks();
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Marshmallow (Re)Routing Info
+    //--------------------
+    /**
+     * Defines the interface by which applications can receive notifications of routing
+     * changes for the associated {@link AudioRecord}.
+     */
+    public interface OnRoutingChangedListener {
+        /**
+         * Called when the routing of an AudioRecord changes from either and explicit or
+         * policy rerouting. Use {@link #getRoutedDevice()} to retrieve the newly routed-from
+         * device.
+         */
+        public void onRoutingChanged(AudioRecord audioRecord);
+    }
+
     /**
      * The list of AudioRecord.OnRoutingChangedListener interface added (with
      * {@link AudioRecord#addOnRoutingChangedListener(OnRoutingChangedListener,android.os.Handler)}
@@ -1276,13 +1356,12 @@
      * the callback. If <code>null</code>, the {@link Handler} associated with the main
      * {@link Looper} will be used.
      */
+    @Deprecated
     public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
             android.os.Handler handler) {
         if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
             synchronized (mRoutingChangeListeners) {
-                if (mRoutingChangeListeners.size() == 0) {
-                    native_enableDeviceCallback();
-                }
+                testEnableNativeRoutingCallbacks();
                 mRoutingChangeListeners.put(
                     listener, new NativeRoutingEventHandlerDelegate(this, listener,
                             handler != null ? handler : new Handler(mInitializationLooper)));
@@ -1291,22 +1370,73 @@
     }
 
     /**
-     * Removes an {@link OnRoutingChangedListener} which has been previously added
+      * Removes an {@link OnRoutingChangedListener} which has been previously added
      * to receive rerouting notifications.
      * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
      */
+    @Deprecated
     public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
         synchronized (mRoutingChangeListeners) {
             if (mRoutingChangeListeners.containsKey(listener)) {
                 mRoutingChangeListeners.remove(listener);
-                if (mRoutingChangeListeners.size() == 0) {
-                    native_disableDeviceCallback();
-                }
+                testDisableNativeRoutingCallbacks();
             }
         }
     }
 
     /**
+     * >= "N" Routing
+     * Helper class to handle the forwarding of native events to the appropriate listener
+     * (potentially) handled in a different thread
+     */
+    private class NativeNewRoutingEventHandlerDelegate {
+        private final Handler mHandler;
+
+        NativeNewRoutingEventHandlerDelegate(final AudioRecord record,
+                                   final AudioRouting.OnRoutingChangedListener listener,
+                                   Handler handler) {
+            // find the looper for our new event handler
+            Looper looper;
+            if (handler != null) {
+                looper = handler.getLooper();
+            } else {
+                // no given handler, use the looper the AudioRecord was created in
+                looper = mInitializationLooper;
+            }
+
+            // construct the event handler with this looper
+            if (looper != null) {
+                // implement the event handler delegate
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        if (record == null) {
+                            return;
+                        }
+                        switch(msg.what) {
+                        case AudioSystem.NATIVE_EVENT_ROUTING_CHANGE:
+                            if (listener != null) {
+                                listener.onRoutingChanged(record);
+                            }
+                            break;
+                        default:
+                            loge("Unknown native event type: " + msg.what);
+                            break;
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler getHandler() {
+            return mHandler;
+        }
+    }
+
+    /**
+     * Marshmallow Routing
      * Helper class to handle the forwarding of native events to the appropriate listener
      * (potentially) handled in a different thread
      */
@@ -1355,21 +1485,34 @@
             return mHandler;
         }
     }
+
     /**
      * Sends device list change notification to all listeners.
      */
     private void broadcastRoutingChange() {
+        AudioManager.resetAudioPortGeneration();
+        // Marshmallow Routing
         Collection<NativeRoutingEventHandlerDelegate> values;
         synchronized (mRoutingChangeListeners) {
             values = mRoutingChangeListeners.values();
         }
-        AudioManager.resetAudioPortGeneration();
         for(NativeRoutingEventHandlerDelegate delegate : values) {
             Handler handler = delegate.getHandler();
             if (handler != null) {
                 handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
             }
         }
+        // >= "N" Routing
+        Collection<NativeNewRoutingEventHandlerDelegate> newValues;
+        synchronized (mNewRoutingChangeListeners) {
+            newValues = mNewRoutingChangeListeners.values();
+        }
+        for(NativeNewRoutingEventHandlerDelegate delegate : newValues) {
+            Handler handler = delegate.getHandler();
+            if (handler != null) {
+                handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
+            }
+        }
     }
 
     /**
diff --git a/media/java/android/media/AudioRecordRoutingProxy.java b/media/java/android/media/AudioRecordRoutingProxy.java
new file mode 100644
index 0000000..b0c19e4
--- /dev/null
+++ b/media/java/android/media/AudioRecordRoutingProxy.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * An AudioRecord connected to a native (C/C++) which allows access only to routing methods.
+ */
+class AudioRecordRoutingProxy extends AudioRecord {
+    /**
+     * A constructor which explicitly connects a Native (C++) AudioRecord. For use by
+     * the AudioRecordRoutingProxy subclass.
+     * @param nativeRecordInJavaObj A C/C++ pointer to a native AudioRecord
+     * (associated with an OpenSL ES recorder).
+     */
+    public AudioRecordRoutingProxy(long nativeRecordInJavaObj) {
+        super(nativeRecordInJavaObj);
+    }
+}
diff --git a/media/java/android/media/AudioRouting.java b/media/java/android/media/AudioRouting.java
new file mode 100644
index 0000000..2161cf3
--- /dev/null
+++ b/media/java/android/media/AudioRouting.java
@@ -0,0 +1,70 @@
+/*
+ * 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.media;
+
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * AudioRouting defines an interface for controlling routing and routing notifications in
+ * AudioTrack and AudioRecord objects.
+ */
+public interface AudioRouting {
+    /**
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
+     * the output/input to/from.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink or source.
+     *  If deviceInfo is null, default routing is restored.
+     * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
+     * does not correspond to a valid audio device.
+     */
+    public boolean setPreferredDevice(AudioDeviceInfo deviceInfo);
+
+    /**
+     * Returns the selected output/input specified by {@link #setPreferredDevice}. Note that this
+     * is not guaranteed to correspond to the actual device being used for playback/recording.
+     */
+    public AudioDeviceInfo getPreferredDevice();
+
+    /**
+     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
+     * changes on this AudioTrack/AudioRecord.
+     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+     * notifications of rerouting events.
+     * @param handler  Specifies 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 addOnRoutingListener(OnRoutingChangedListener listener,
+            Handler handler);
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+     * to remove.
+     */
+    public void removeOnRoutingListener(OnRoutingChangedListener listener);
+
+    /**
+     * Defines the interface by which applications can receive notifications of routing
+     * changes for the associated {@link AudioRouting}.
+     */
+    public interface OnRoutingChangedListener {
+        public void onRoutingChanged(AudioRouting router);
+    }
+}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index a810ff1..4319840 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -42,7 +42,6 @@
 
 import com.android.internal.app.IAppOpsService;
 
-
 /**
  * The AudioTrack class manages and plays a single audio resource for Java applications.
  * It allows streaming of PCM audio buffers to the audio sink for playback. This is
@@ -78,7 +77,7 @@
  *
  * AudioTrack is not final and thus permits subclasses, but such use is not recommended.
  */
-public class AudioTrack
+public class AudioTrack implements AudioRouting
 {
     //---------------------------------------------------------
     // Constants
@@ -318,10 +317,11 @@
     // Used exclusively by native code
     //--------------------
     /**
+     * @hide
      * Accessed by native methods: provides access to C++ AudioTrack object.
      */
     @SuppressWarnings("unused")
-    private long mNativeTrackInJavaObj;
+    protected long mNativeTrackInJavaObj;
     /**
      * Accessed by native methods: provides access to the JNI data (i.e. resources used by
      * the native AudioTrack object, but not stored in it).
@@ -524,6 +524,31 @@
     }
 
     /**
+     * A constructor which explicitly connects a Native (C++) AudioTrack. For use by
+     * the AudioTrackRoutingProxy subclass.
+     * @param nativeTrackInJavaObj a C/C++ pointer to a native AudioTrack
+     * (associated with an OpenSL ES player).
+     */
+    /*package*/ AudioTrack(long nativeTrackInJavaObj) {
+        mNativeTrackInJavaObj = nativeTrackInJavaObj;
+
+        // "final"s
+        mAttributes = null;
+        mAppOps = null;
+
+        // remember which looper is associated with the AudioTrack instantiation
+        Looper looper;
+        if ((looper = Looper.myLooper()) == null) {
+            looper = Looper.getMainLooper();
+        }
+        mInitializationLooper = looper;
+
+        // other initialization...
+
+        mState = STATE_INITIALIZED;
+    }
+
+    /**
      * Builder class for {@link AudioTrack} objects.
      * Use this class to configure and create an <code>AudioTrack</code> instance. By setting audio
      * attributes and audio format parameters, you indicate which of those vary from the default
@@ -1027,8 +1052,68 @@
         }
     }
 
+// TODO Change getBufferCapacityInFrames() reference below to
+// {@link #getBufferCapacityInFrames()} after @hide is removed.
+// TODO Change setBufferSizeInFrames(int) reference below to
+// {@link #setBufferSizeInFrames(int)} after @hide is removed.
     /**
-     *  Returns the frame count of the native <code>AudioTrack</code> buffer.
+     *  Returns the effective size of the <code>AudioTrack</code> buffer
+     * that the application writes to.
+     *  <p> This will be less than or equal to the result of
+     * getBufferCapacityInFrames().
+     * It will be equal if setBufferSizeInFrames(int) has never been called.
+     *  <p> If the track is subsequently routed to a different output sink, the buffer
+     *  size and capacity may enlarge to accommodate.
+     *  <p> If the <code>AudioTrack</code> encoding indicates compressed data,
+     *  e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
+     *  the size of the native <code>AudioTrack</code> buffer in bytes.
+     *  <p> See also {@link AudioManager#getProperty(String)} for key
+     *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
+     *  @return current size in frames of the <code>AudioTrack</code> buffer.
+     *  @throws IllegalStateException
+     */
+    public int getBufferSizeInFrames() {
+        return native_get_buffer_size_frames();
+    }
+
+// TODO Change getBufferCapacityInFrames() reference below to
+// {@link #getBufferCapacityInFrames()} after @hide is removed.
+    /**
+     * Limits the effective size of the <code>AudioTrack</code> buffer
+     * that the application writes to.
+     * <p> A write to this AudioTrack will not fill the buffer beyond this limit.
+     * If a blocking write is used then the write will block until the the data
+     * can fit within this limit.
+     * <p>Changing this limit modifies the latency associated with
+     * the buffer for this track. A smaller size will give lower latency
+     * but there may be more glitches due to buffer underruns.
+     *  <p>The actual size used may not be equal to this requested size.
+     * It will be limited to a valid range with a maximum of
+     * getBufferCapacityInFrames().
+     * It may also be adjusted slightly for internal reasons.
+     * If bufferSizeInFrames is less than zero then {@link #ERROR_BAD_VALUE}
+     * will be returned.
+     * <p>This method is only supported for PCM audio.
+     * It is not supported for compressed audio tracks.
+     *
+     * @param bufferSizeInFrames requested buffer size
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+     *    {@link #ERROR_INVALID_OPERATION}
+     *  @throws IllegalStateException
+     * @hide
+     */
+    public int setBufferSizeInFrames(int bufferSizeInFrames) {
+        if (mDataLoadMode == MODE_STATIC || mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        if (bufferSizeInFrames < 0) {
+            return ERROR_BAD_VALUE;
+        }
+        return native_set_buffer_size_frames(bufferSizeInFrames);
+    }
+
+    /**
+     *  Returns the maximum size of the native <code>AudioTrack</code> buffer.
      *  <p> If the track's creation mode is {@link #MODE_STATIC},
      *  it is equal to the specified bufferSizeInBytes on construction, converted to frame units.
      *  A static track's native frame count will not change.
@@ -1043,11 +1128,12 @@
      *  the size of the native <code>AudioTrack</code> buffer in bytes.
      *  <p> See also {@link AudioManager#getProperty(String)} for key
      *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
-     *  @return current size in frames of the <code>AudioTrack</code> buffer.
+     *  @return maximum size in frames of the <code>AudioTrack</code> buffer.
      *  @throws IllegalStateException
+     * @hide
      */
-    public int getBufferSizeInFrames() {
-        return native_get_native_frame_count();
+    public int getBufferCapacityInFrames() {
+        return native_get_buffer_capacity_frames();
     }
 
     /**
@@ -1058,7 +1144,7 @@
      */
     @Deprecated
     protected int getNativeFrameCount() {
-        return native_get_native_frame_count();
+        return native_get_buffer_capacity_frames();
     }
 
     /**
@@ -1106,6 +1192,25 @@
     }
 
     /**
+     * Returns the number of underrun occurrences in the application-level write buffer
+     * since the AudioTrack was created.
+     * An underrun occurs if the application does not write audio
+     * data quickly enough, causing the buffer to underflow
+     * and a potential audio glitch or pop.
+     * Underruns are less likely when buffer sizes are large.
+     * <p> Though the "int" type is signed 32-bits, the value should be reinterpreted
+     * as if it is unsigned 32-bits.
+     * That is, the next position after 0x7FFFFFFF is (int) 0x80000000.
+     * This is a continuously advancing counter. It can wrap around to zero
+     * if there are too many underruns. If there were, for example, 68 underruns per
+     * second then the counter would wrap in 2 years.
+     * @hide
+     */
+    public int getUnderrunCount() {
+        return native_get_underrun_count();
+    }
+
+    /**
      *  Returns the output sample rate in Hz for the specified stream type.
      */
     static public int getNativeOutputSampleRate(int streamType) {
@@ -2247,22 +2352,6 @@
         }
     }
 
-    //--------------------------------------------------------------------------
-    // (Re)Routing Info
-    //--------------------
-    /**
-     * Defines the interface by which applications can receive notifications of routing
-     * changes for the associated {@link AudioTrack}.
-     */
-    public interface OnRoutingChangedListener {
-        /**
-         * Called when the routing of an AudioTrack changes from either and explicit or
-         * policy rerouting.  Use {@link #getRoutedDevice()} to retrieve the newly routed-to
-         * device.
-         */
-        public void onRoutingChanged(AudioTrack audioTrack);
-    }
-
     /**
      * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack.
      * Note: The query is only valid if the AudioTrack is currently playing. If it is not,
@@ -2283,6 +2372,89 @@
         return null;
     }
 
+    /*
+     * Call BEFORE adding a routing callback handler.
+     */
+    private void testEnableNativeRoutingCallbacks() {
+        if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
+            native_enableDeviceCallback();
+        }
+    }
+
+    /*
+     * Call AFTER removing a routing callback handler.
+     */
+    private void testDisableNativeRoutingCallbacks() {
+        if (mRoutingChangeListeners.size() == 0 && mNewRoutingChangeListeners.size() == 0) {
+            native_disableDeviceCallback();
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // >= "N" (Re)Routing Info
+    //--------------------
+    /**
+     * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
+     * {@link AudioTrack#addOnRoutingListener(AudioRouting.OnRoutingChangedListener,
+     *          android.os.Handler)}
+     * by an app to receive (re)routing notifications.
+     */
+   private ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>
+    mNewRoutingChangeListeners =
+        new ArrayMap<AudioRouting.OnRoutingChangedListener, NativeNewRoutingEventHandlerDelegate>();
+
+   /**
+    * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
+    * changes on this AudioTrack.
+    * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+    * notifications of rerouting events.
+    * @param handler  Specifies 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 addOnRoutingListener(AudioRouting.OnRoutingChangedListener listener,
+            Handler handler) {
+        if (listener != null && !mNewRoutingChangeListeners.containsKey(listener)) {
+            synchronized (mNewRoutingChangeListeners) {
+                testEnableNativeRoutingCallbacks();
+                mNewRoutingChangeListeners.put(
+                    listener, new NativeNewRoutingEventHandlerDelegate(this, listener,
+                            handler != null ? handler : new Handler(mInitializationLooper)));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+     * to remove.
+     */
+    public void removeOnRoutingListener(AudioRouting.OnRoutingChangedListener listener) {
+        if (mNewRoutingChangeListeners.containsKey(listener)) {
+            mNewRoutingChangeListeners.remove(listener);
+        }
+        testDisableNativeRoutingCallbacks();
+    }
+
+    //--------------------------------------------------------------------------
+    // Marshmallow (Re)Routing Info
+    //--------------------
+    /**
+     * Defines the interface by which applications can receive notifications of routing
+     * changes for the associated {@link AudioTrack}.
+     */
+    @Deprecated
+    public interface OnRoutingChangedListener {
+        /**
+         * Called when the routing of an AudioTrack changes from either and explicit or
+         * policy rerouting.  Use {@link #getRoutedDevice()} to retrieve the newly routed-to
+         * device.
+         */
+        @Deprecated
+        public void onRoutingChanged(AudioTrack audioTrack);
+    }
+
     /**
      * The list of AudioTrack.OnRoutingChangedListener interfaces added (with
      * {@link AudioTrack#addOnRoutingChangedListener(OnRoutingChangedListener, android.os.Handler)}
@@ -2301,13 +2473,12 @@
      * the callback. If <code>null</code>, the {@link Handler} associated with the main
      * {@link Looper} will be used.
      */
+    @Deprecated
     public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
             android.os.Handler handler) {
         if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
             synchronized (mRoutingChangeListeners) {
-                if (mRoutingChangeListeners.size() == 0) {
-                    native_enableDeviceCallback();
-                }
+                testEnableNativeRoutingCallbacks();
                 mRoutingChangeListeners.put(
                     listener, new NativeRoutingEventHandlerDelegate(this, listener,
                             handler != null ? handler : new Handler(mInitializationLooper)));
@@ -2320,14 +2491,13 @@
      * to receive rerouting notifications.
      * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
      */
+    @Deprecated
     public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
         synchronized (mRoutingChangeListeners) {
             if (mRoutingChangeListeners.containsKey(listener)) {
                 mRoutingChangeListeners.remove(listener);
             }
-            if (mRoutingChangeListeners.size() == 0) {
-                native_disableDeviceCallback();
-            }
+            testDisableNativeRoutingCallbacks();
         }
     }
 
@@ -2335,17 +2505,30 @@
      * Sends device list change notification to all listeners.
      */
     private void broadcastRoutingChange() {
+        AudioManager.resetAudioPortGeneration();
+
+        // Marshmallow Routing
         Collection<NativeRoutingEventHandlerDelegate> values;
         synchronized (mRoutingChangeListeners) {
             values = mRoutingChangeListeners.values();
         }
-        AudioManager.resetAudioPortGeneration();
         for(NativeRoutingEventHandlerDelegate delegate : values) {
             Handler handler = delegate.getHandler();
             if (handler != null) {
                 handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
             }
         }
+        // >= "N" Routing
+        Collection<NativeNewRoutingEventHandlerDelegate> newValues;
+        synchronized (mNewRoutingChangeListeners) {
+            newValues = mNewRoutingChangeListeners.values();
+        }
+        for(NativeNewRoutingEventHandlerDelegate delegate : newValues) {
+            Handler handler = delegate.getHandler();
+            if (handler != null) {
+                handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
+            }
+        }
     }
 
     //---------------------------------------------------------
@@ -2428,6 +2611,7 @@
     }
 
     /**
+     * Marshmallow Routing API.
      * Helper class to handle the forwarding of native events to the appropriate listener
      * (potentially) handled in a different thread
      */
@@ -2477,6 +2661,57 @@
         }
     }
 
+    /**
+     * Marshmallow Routing API.
+     * Helper class to handle the forwarding of native events to the appropriate listener
+     * (potentially) handled in a different thread
+     */
+    private class NativeNewRoutingEventHandlerDelegate {
+        private final Handler mHandler;
+
+        NativeNewRoutingEventHandlerDelegate(final AudioTrack track,
+                                   final AudioRouting.OnRoutingChangedListener listener,
+                                   Handler handler) {
+            // find the looper for our new event handler
+            Looper looper;
+            if (handler != null) {
+                looper = handler.getLooper();
+            } else {
+                // no given handler, use the looper the AudioTrack was created in
+                looper = mInitializationLooper;
+            }
+
+            // construct the event handler with this looper
+            if (looper != null) {
+                // implement the event handler delegate
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        if (track == null) {
+                            return;
+                        }
+                        switch(msg.what) {
+                        case AudioSystem.NATIVE_EVENT_ROUTING_CHANGE:
+                            if (listener != null) {
+                                listener.onRoutingChanged(track);
+                            }
+                            break;
+                        default:
+                            loge("Unknown native event type: " + msg.what);
+                            break;
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler getHandler() {
+            return mHandler;
+        }
+    }
+
     //---------------------------------------------------------
     // Java methods called from the native side
     //--------------------
@@ -2545,7 +2780,9 @@
 
     private native final int native_reload_static();
 
-    private native final int native_get_native_frame_count();
+    private native final int native_get_buffer_size_frames();
+    private native final int native_set_buffer_size_frames(int bufferSizeInFrames);
+    private native final int native_get_buffer_capacity_frames();
 
     private native final void native_setVolume(float leftVolume, float rightVolume);
 
@@ -2566,6 +2803,8 @@
 
     private native final int native_get_latency();
 
+    private native final int native_get_underrun_count();
+
     // longArray must be a non-null array of length >= 2
     // [0] is assigned the frame position
     // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
diff --git a/media/java/android/media/AudioTrackRoutingProxy.java b/media/java/android/media/AudioTrackRoutingProxy.java
new file mode 100644
index 0000000..9b97ae9
--- /dev/null
+++ b/media/java/android/media/AudioTrackRoutingProxy.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * An AudioTrack connected to a native (C/C++) which allows access only to routing methods.
+ */
+class AudioTrackRoutingProxy extends AudioTrack {
+    /**
+     * A constructor which explicitly connects a Native (C++) AudioTrack. For use by
+     * the AudioTrackRoutingProxy subclass.
+     * @param nativeTrackInJavaObj a C/C++ pointer to a native AudioTrack
+     * (associated with an OpenSL ES player).
+     */
+    public AudioTrackRoutingProxy(long nativeTrackInJavaObj) {
+        super(nativeTrackInJavaObj);
+    }
+}
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/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 445ee6f..7fb67ee 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -17,7 +17,7 @@
 package android.media;
 
 import java.io.IOException;
-import java.util.regex.Matcher;
+import java.io.RandomAccessFile;
 import java.util.regex.Pattern;
 import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
@@ -27,7 +27,9 @@
 import java.util.TimeZone;
 
 /**
- * This is a class for reading and writing Exif tags in a JPEG file.
+ * This is a class for reading and writing Exif tags in a JPEG file or a RAW image file.
+ * <p>
+ * Supported formats are: JPEG, DNG, CR2, NEF, NRW, ARW, RW2, ORF and RAF.
  */
 public class ExifInterface {
     // The Exif tag names
@@ -68,8 +70,6 @@
     /** Type is int. */
     public static final String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized";
 
-
-
     /**
      * @hide
      */
@@ -98,15 +98,22 @@
     /** Type is String. Name of GPS processing method used for location finding. */
     public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
 
+    // Private tags used for thumbnail information.
+    private static final String TAG_HAS_THUMBNAIL = "hasThumbnail";
+    private static final String TAG_THUMBNAIL_OFFSET = "thumbnailOffset";
+    private static final String TAG_THUMBNAIL_LENGTH = "thumbnailLength";
+
     // Constants used for the Orientation Exif tag.
     public static final int ORIENTATION_UNDEFINED = 0;
     public static final int ORIENTATION_NORMAL = 1;
     public static final int ORIENTATION_FLIP_HORIZONTAL = 2;  // left right reversed mirror
     public static final int ORIENTATION_ROTATE_180 = 3;
     public static final int ORIENTATION_FLIP_VERTICAL = 4;  // upside down mirror
-    public static final int ORIENTATION_TRANSPOSE = 5;  // flipped about top-left <--> bottom-right axis
+    // flipped about top-left <--> bottom-right axis
+    public static final int ORIENTATION_TRANSPOSE = 5;
     public static final int ORIENTATION_ROTATE_90 = 6;  // rotate 90 cw to right it
-    public static final int ORIENTATION_TRANSVERSE = 7;  // flipped about top-right <--> bottom-left axis
+    // flipped about top-right <--> bottom-left axis
+    public static final int ORIENTATION_TRANSVERSE = 7;
     public static final int ORIENTATION_ROTATE_270 = 8;  // rotate 270 to right it
 
     // Constants used for white balance
@@ -116,13 +123,20 @@
 
     static {
         System.loadLibrary("jhead_jni");
+        System.loadLibrary("media_jni");
+        initRawNative();
+
         sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
         sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
     }
 
-    private String mFilename;
-    private HashMap<String, String> mAttributes;
+    private final String mFilename;
+    private final HashMap<String, String> mAttributes = new HashMap<>();
+    private boolean mIsRaw;
     private boolean mHasThumbnail;
+    // The following values used for indicating a thumbnail position.
+    private int mThumbnailOffset;
+    private int mThumbnailLength;
 
     // Because the underlying implementation (jhead) uses static variables,
     // there can only be one user at a time for the native functions (and
@@ -134,19 +148,20 @@
     private static final Pattern sNonZeroTimePattern = Pattern.compile(".*[1-9].*");
 
     /**
-     * Reads Exif tags from the specified JPEG file.
+     * Reads Exif tags from the specified image file.
      */
     public ExifInterface(String filename) throws IOException {
         if (filename == null) {
             throw new IllegalArgumentException("filename cannot be null");
         }
         mFilename = filename;
+        // First test whether a given file is a one of RAW format or not.
         loadAttributes();
     }
 
     /**
      * Returns the value of the specified tag or {@code null} if there
-     * is no such tag in the JPEG file.
+     * is no such tag in the image file.
      *
      * @param tag the name of the tag.
      */
@@ -156,7 +171,7 @@
 
     /**
      * Returns the integer value of the specified tag. If there is no such tag
-     * in the JPEG file or the value cannot be parsed as integer, return
+     * in the image file or the value cannot be parsed as integer, return
      * <var>defaultValue</var>.
      *
      * @param tag the name of the tag.
@@ -174,7 +189,7 @@
 
     /**
      * Returns the double value of the specified rational tag. If there is no
-     * such tag in the JPEG file or the value cannot be parsed as double, return
+     * such tag in the image file or the value cannot be parsed as double, return
      * <var>defaultValue</var>.
      *
      * @param tag the name of the tag.
@@ -210,17 +225,42 @@
      *
      * mAttributes is a HashMap which stores the Exif attributes of the file.
      * The key is the standard tag name and the value is the tag's value: e.g.
-     * Model -> Nikon. Numeric values are stored as strings.
+     * Model -&gt; Nikon. Numeric values are stored as strings.
      *
      * This function also initialize mHasThumbnail to indicate whether the
      * file has a thumbnail inside.
      */
     private void loadAttributes() throws IOException {
+        HashMap map = getRawAttributesNative(mFilename);
+        mIsRaw = map != null;
+        if (mIsRaw) {
+            for (Object o : map.entrySet()) {
+                Map.Entry entry = (Map.Entry) o;
+                String attrName = (String) entry.getKey();
+                String attrValue = (String) entry.getValue();
+
+                switch (attrName) {
+                    case TAG_HAS_THUMBNAIL:
+                        mHasThumbnail = attrValue.equalsIgnoreCase("true");
+                        break;
+                    case TAG_THUMBNAIL_OFFSET:
+                        mThumbnailOffset = Integer.parseInt(attrValue);
+                        break;
+                    case TAG_THUMBNAIL_LENGTH:
+                        mThumbnailLength = Integer.parseInt(attrValue);
+                        break;
+                    default:
+                        mAttributes.put(attrName, attrValue);
+                        break;
+                }
+            }
+            return;
+        }
+
         // format of string passed from native C code:
         // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
         // example:
         // "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"
-        mAttributes = new HashMap<String, String>();
 
         String attrStr;
         synchronized (sLock) {
@@ -248,7 +288,7 @@
             String attrValue = attrStr.substring(ptr, ptr + attrLen);
             ptr += attrLen;
 
-            if (attrName.equals("hasThumbnail")) {
+            if (attrName.equals(TAG_HAS_THUMBNAIL)) {
                 mHasThumbnail = attrValue.equalsIgnoreCase("true");
             } else {
                 mAttributes.put(attrName, attrValue);
@@ -257,32 +297,36 @@
     }
 
     /**
-     * Save the tag data into the JPEG file. This is expensive because it involves
-     * copying all the JPG data from one file to another and deleting the old file
-     * and renaming the other. It's best to use {@link #setAttribute(String,String)}
-     * to set all attributes to write and make a single call rather than multiple
-     * calls for each attribute.
+     * Save the tag data into the original image file. This is expensive because it involves
+     * copying all the data from one file to another and deleting the old file and renaming the
+     * other. It's best to use{@link #setAttribute(String,String)} to set all attributes to write
+     * and make a single call rather than multiple calls for each attribute.
      */
     public void saveAttributes() throws IOException {
+        if (mIsRaw) {
+            throw new UnsupportedOperationException(
+                    "ExifInterface does not support saving attributes on RAW formats.");
+        }
+
         // format of string passed to native C code:
         // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
         // example:
         // "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"
         StringBuilder sb = new StringBuilder();
         int size = mAttributes.size();
-        if (mAttributes.containsKey("hasThumbnail")) {
+        if (mAttributes.containsKey(TAG_HAS_THUMBNAIL)) {
             --size;
         }
-        sb.append(size + " ");
-        for (Map.Entry<String, String> iter : mAttributes.entrySet()) {
-            String key = iter.getKey();
-            if (key.equals("hasThumbnail")) {
+        sb.append(size).append(" ");
+        for (Map.Entry<String, String> entry : mAttributes.entrySet()) {
+            String key = entry.getKey();
+            if (key.equals(TAG_HAS_THUMBNAIL)) {
                 // this is a fake attribute not saved as an exif tag
                 continue;
             }
-            String val = iter.getValue();
-            sb.append(key + "=");
-            sb.append(val.length() + " ");
+            String val = entry.getValue();
+            sb.append(key).append("=");
+            sb.append(val.length()).append(" ");
             sb.append(val);
         }
         String s = sb.toString();
@@ -293,25 +337,43 @@
     }
 
     /**
-     * Returns true if the JPEG file has a thumbnail.
+     * Returns true if the image file has a thumbnail.
      */
     public boolean hasThumbnail() {
         return mHasThumbnail;
     }
 
     /**
-     * Returns the thumbnail inside the JPEG file, or {@code null} if there is no thumbnail.
+     * Returns the thumbnail inside the image file, or {@code null} if there is no thumbnail.
      * The returned data is in JPEG format and can be decoded using
      * {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}
      */
     public byte[] getThumbnail() {
+        if (mIsRaw) {
+            if (mHasThumbnail) {
+                try (RandomAccessFile file = new RandomAccessFile(mFilename, "r")) {
+                    if (file.length() < mThumbnailLength + mThumbnailOffset) {
+                        throw new IOException("Corrupted image.");
+                    }
+                    file.seek(mThumbnailOffset);
+
+                    byte[] buffer = new byte[mThumbnailLength];
+                    file.readFully(buffer);
+                    return buffer;
+                } catch (IOException e) {
+                    // Couldn't get a thumbnail image.
+                }
+            }
+            return null;
+        }
+
         synchronized (sLock) {
             return getThumbnailNative(mFilename);
         }
     }
 
     /**
-     * Returns the offset and length of thumbnail inside the JPEG file, or
+     * Returns the offset and length of thumbnail inside the image file, or
      * {@code null} if there is no thumbnail.
      *
      * @return two-element array, the offset in the first value, and length in
@@ -319,6 +381,13 @@
      * @hide
      */
     public long[] getThumbnailRange() {
+        if (mIsRaw) {
+            long[] range = new long[2];
+            range[0] = mThumbnailOffset;
+            range[1] = mThumbnailLength;
+            return range;
+        }
+
         synchronized (sLock) {
             return getThumbnailRangeNative(mFilename);
         }
@@ -447,26 +516,28 @@
                 return (float) -result;
             }
             return (float) result;
-        } catch (NumberFormatException e) {
-            // Some of the nubmers are not valid
-            throw new IllegalArgumentException();
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // Some of the rational does not follow the correct format
+        } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
+            // Not valid
             throw new IllegalArgumentException();
         }
     }
 
-    private native boolean appendThumbnailNative(String fileName,
+    // JNI methods for JPEG.
+    private static native boolean appendThumbnailNative(String fileName,
             String thumbnailFileName);
 
-    private native void saveAttributesNative(String fileName,
+    private static native void saveAttributesNative(String fileName,
             String compressedAttributes);
 
-    private native String getAttributesNative(String fileName);
+    private static native String getAttributesNative(String fileName);
 
-    private native void commitChangesNative(String fileName);
+    private static native void commitChangesNative(String fileName);
 
-    private native byte[] getThumbnailNative(String fileName);
+    private static native byte[] getThumbnailNative(String fileName);
 
-    private native long[] getThumbnailRangeNative(String fileName);
+    private static native long[] getThumbnailRangeNative(String fileName);
+
+    // JNI methods for RAW formats.
+    private static native void initRawNative();
+    private static native HashMap getRawAttributesNative(String filename);
 }
diff --git a/media/java/android/media/IMediaResourceMonitor.aidl b/media/java/android/media/IMediaResourceMonitor.aidl
new file mode 100644
index 0000000..7b4bc39
--- /dev/null
+++ b/media/java/android/media/IMediaResourceMonitor.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/** {@hide} */
+interface IMediaResourceMonitor
+{
+    oneway void notifyResourceGranted(in int pid, String type, String subType, long value);
+}
+
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 526656a..7d76e74 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -52,7 +52,7 @@
     public static final int FILE_TYPE_IMY     = 13;
     private static final int FIRST_MIDI_FILE_TYPE = FILE_TYPE_MID;
     private static final int LAST_MIDI_FILE_TYPE = FILE_TYPE_IMY;
-   
+
     // Video file types
     public static final int FILE_TYPE_MP4     = 21;
     public static final int FILE_TYPE_M4V     = 22;
@@ -66,7 +66,7 @@
     public static final int FILE_TYPE_WEBM    = 30;
     private static final int FIRST_VIDEO_FILE_TYPE = FILE_TYPE_MP4;
     private static final int LAST_VIDEO_FILE_TYPE = FILE_TYPE_WEBM;
-    
+
     // More video file types
     public static final int FILE_TYPE_MP2PS   = 200;
     private static final int FIRST_VIDEO_FILE_TYPE2 = FILE_TYPE_MP2PS;
@@ -81,7 +81,19 @@
     public static final int FILE_TYPE_WEBP    = 36;
     private static final int FIRST_IMAGE_FILE_TYPE = FILE_TYPE_JPEG;
     private static final int LAST_IMAGE_FILE_TYPE = FILE_TYPE_WEBP;
-   
+
+    // Raw image file types
+    public static final int FILE_TYPE_DNG     = 300;
+    public static final int FILE_TYPE_CR2     = 301;
+    public static final int FILE_TYPE_NEF     = 302;
+    public static final int FILE_TYPE_NRW     = 303;
+    public static final int FILE_TYPE_ARW     = 304;
+    public static final int FILE_TYPE_RW2     = 305;
+    public static final int FILE_TYPE_ORF     = 306;
+    public static final int FILE_TYPE_RAF     = 307;
+    private static final int FIRST_RAW_IMAGE_FILE_TYPE = FILE_TYPE_DNG;
+    private static final int LAST_RAW_IMAGE_FILE_TYPE = FILE_TYPE_RAF;
+
     // Playlist file types
     public static final int FILE_TYPE_M3U      = 41;
     public static final int FILE_TYPE_PLS      = 42;
@@ -105,17 +117,17 @@
     public static final int FILE_TYPE_MS_EXCEL      = 105;
     public static final int FILE_TYPE_MS_POWERPOINT = 106;
     public static final int FILE_TYPE_ZIP           = 107;
-    
+
     public static class MediaFileType {
         public final int fileType;
         public final String mimeType;
-        
+
         MediaFileType(int fileType, String mimeType) {
             this.fileType = fileType;
             this.mimeType = mimeType;
         }
     }
-    
+
     private static final HashMap<String, MediaFileType> sFileTypeMap
             = new HashMap<String, MediaFileType>();
     private static final HashMap<String, Integer> sMimeTypeMap
@@ -182,7 +194,7 @@
         addFileType("AAC", FILE_TYPE_AAC, "audio/aac", MtpConstants.FORMAT_AAC);
         addFileType("AAC", FILE_TYPE_AAC, "audio/aac-adts", MtpConstants.FORMAT_AAC);
         addFileType("MKA", FILE_TYPE_MKA, "audio/x-matroska");
- 
+
         addFileType("MID", FILE_TYPE_MID, "audio/midi");
         addFileType("MIDI", FILE_TYPE_MID, "audio/midi");
         addFileType("XMF", FILE_TYPE_MID, "audio/midi");
@@ -192,7 +204,7 @@
         addFileType("RTX", FILE_TYPE_MID, "audio/midi");
         addFileType("OTA", FILE_TYPE_MID, "audio/midi");
         addFileType("MXMF", FILE_TYPE_MID, "audio/midi");
-        
+
         addFileType("MPEG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG);
         addFileType("MPG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG);
         addFileType("MP4", FILE_TYPE_MP4, "video/mp4", MtpConstants.FORMAT_MPEG);
@@ -218,7 +230,16 @@
         addFileType("BMP", FILE_TYPE_BMP, "image/x-ms-bmp", MtpConstants.FORMAT_BMP);
         addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp");
         addFileType("WEBP", FILE_TYPE_WEBP, "image/webp");
- 
+
+        addFileType("DNG", FILE_TYPE_DNG, "image/x-adobe-dng", MtpConstants.FORMAT_DNG);
+        addFileType("CR2", FILE_TYPE_CR2, "image/x-canon-cr2");
+        addFileType("NEF", FILE_TYPE_NEF, "image/x-nikon-nef");
+        addFileType("NRW", FILE_TYPE_NRW, "image/x-nikon-nrw");
+        addFileType("ARW", FILE_TYPE_ARW, "image/x-sony-arw");
+        addFileType("RW2", FILE_TYPE_RW2, "image/x-panasonic-rw2");
+        addFileType("ORF", FILE_TYPE_ORF, "image/x-olympus-orf");
+        addFileType("RAF", FILE_TYPE_RAF, "image/x-fuji-raf");
+
         addFileType("M3U", FILE_TYPE_M3U, "audio/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
         addFileType("M3U", FILE_TYPE_M3U, "application/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
         addFileType("PLS", FILE_TYPE_PLS, "audio/x-scpls", MtpConstants.FORMAT_PLS_PLAYLIST);
@@ -258,7 +279,14 @@
 
     public static boolean isImageFileType(int fileType) {
         return (fileType >= FIRST_IMAGE_FILE_TYPE &&
-                fileType <= LAST_IMAGE_FILE_TYPE);
+                fileType <= LAST_IMAGE_FILE_TYPE)
+            || (fileType >= FIRST_RAW_IMAGE_FILE_TYPE &&
+                fileType <= LAST_RAW_IMAGE_FILE_TYPE);
+    }
+
+    public static boolean isRawImageFileType(int fileType) {
+        return (fileType >= FIRST_RAW_IMAGE_FILE_TYPE &&
+                fileType <= LAST_RAW_IMAGE_FILE_TYPE);
     }
 
     public static boolean isPlayListFileType(int fileType) {
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/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 8ac86b0..504c6d0 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -251,6 +251,10 @@
          */
         public static final int REMOTE_SUBMIX = 8;
 
+        /** Microphone audio source tuned for unprocessed (raw) sound if available, behaves like
+         *  {@link #DEFAULT} otherwise. */
+        public static final int UNPROCESSED = 9;
+
         /**
          * Audio source for capturing broadcast radio tuner output.
          * @hide
@@ -405,7 +409,7 @@
      * @see android.media.MediaRecorder.AudioSource
      */
     public static final int getAudioSourceMax() {
-        return AudioSource.REMOTE_SUBMIX;
+        return AudioSource.UNPROCESSED;
     }
 
     /**
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 96c616b..78f357f 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import android.content.ContentProviderClient;
+import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
@@ -37,6 +38,7 @@
 import android.provider.MediaStore.Images;
 import android.provider.MediaStore.Video;
 import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
 import android.sax.Element;
 import android.sax.ElementListener;
 import android.sax.RootElement;
@@ -328,8 +330,6 @@
     // used when scanning the image database so we know whether we have to prune
     // old thumbnail files
     private int mOriginalCount;
-    /** Whether the database had any entries in it before the scan started */
-    private boolean mWasEmptyPriorToScan = false;
     /** Whether the scanner has set a default sound for the ringer ringtone. */
     private boolean mDefaultRingtoneSet;
     /** Whether the scanner has set a default sound for the notification ringtone. */
@@ -562,12 +562,29 @@
                 FileEntry entry = beginFile(path, mimeType, lastModified,
                         fileSize, isDirectory, noMedia);
 
+                if (entry == null) {
+                    return null;
+                }
+
                 // if this file was just inserted via mtp, set the rowid to zero
                 // (even though it already exists in the database), to trigger
                 // the correct code path for updating its entry
                 if (mMtpObjectHandle != 0) {
                     entry.mRowId = 0;
                 }
+
+                if (entry.mPath != null &&
+                        ((!mDefaultNotificationSet &&
+                                doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename))
+                        || (!mDefaultRingtoneSet &&
+                                doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename))
+                        || (!mDefaultAlarmSet &&
+                                doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)))) {
+                    Log.w(TAG, "forcing rescan of " + entry.mPath +
+                            "since ringtone setting didn't finish");
+                    scanAlways = true;
+                }
+
                 // rescan for metadata if file was modified since last scan
                 if (entry != null && (entry.mLastModifiedChanged || scanAlways)) {
                     if (noMedia) {
@@ -882,7 +899,8 @@
                 values.put(Audio.Media.IS_ALARM, alarms);
                 values.put(Audio.Media.IS_MUSIC, music);
                 values.put(Audio.Media.IS_PODCAST, podcasts);
-            } else if (mFileType == MediaFile.FILE_TYPE_JPEG && !mNoMedia) {
+            } else if ((mFileType == MediaFile.FILE_TYPE_JPEG
+                    || MediaFile.isRawImageFileType(mFileType)) && !mNoMedia) {
                 ExifInterface exif = null;
                 try {
                     exif = new ExifInterface(entry.mPath);
@@ -947,6 +965,26 @@
             }
             Uri result = null;
             boolean needToSetSettings = false;
+            // Setting a flag in order not to use bulk insert for the file related with
+            // notifications, ringtones, and alarms, because the rowId of the inserted file is
+            // needed.
+            if (notifications && !mDefaultNotificationSet) {
+                if (TextUtils.isEmpty(mDefaultNotificationFilename) ||
+                        doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) {
+                    needToSetSettings = true;
+                }
+            } else if (ringtones && !mDefaultRingtoneSet) {
+                if (TextUtils.isEmpty(mDefaultRingtoneFilename) ||
+                        doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) {
+                    needToSetSettings = true;
+                }
+            } else if (alarms && !mDefaultAlarmSet) {
+                if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) ||
+                        doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) {
+                    needToSetSettings = true;
+                }
+            }
+
             if (rowId == 0) {
                 if (mMtpObjectHandle != 0) {
                     values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle);
@@ -958,28 +996,6 @@
                     }
                     values.put(Files.FileColumns.FORMAT, format);
                 }
-                // Setting a flag in order not to use bulk insert for the file related with
-                // notifications, ringtones, and alarms, because the rowId of the inserted file is
-                // needed.
-                if (mWasEmptyPriorToScan) {
-                    if (notifications && !mDefaultNotificationSet) {
-                        if (TextUtils.isEmpty(mDefaultNotificationFilename) ||
-                                doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) {
-                            needToSetSettings = true;
-                        }
-                    } else if (ringtones && !mDefaultRingtoneSet) {
-                        if (TextUtils.isEmpty(mDefaultRingtoneFilename) ||
-                                doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) {
-                            needToSetSettings = true;
-                        }
-                    } else if (alarms && !mDefaultAlarmSet) {
-                        if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) ||
-                                doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) {
-                            needToSetSettings = true;
-                        }
-                    }
-                }
-
                 // New file, insert it.
                 // Directories need to be inserted before the files they contain, so they
                 // get priority when bulk inserting.
@@ -1049,14 +1065,18 @@
 
         private void setSettingIfNotSet(String settingName, Uri uri, long rowId) {
 
-            String existingSettingValue = Settings.System.getString(mContext.getContentResolver(),
-                    settingName);
+            if(wasSettingAlreadySet(settingName)) {
+                return;
+            }
 
+            ContentResolver cr = mContext.getContentResolver();
+            String existingSettingValue = Settings.System.getString(cr, settingName);
             if (TextUtils.isEmpty(existingSettingValue)) {
                 // Set the setting to the given URI
-                Settings.System.putString(mContext.getContentResolver(), settingName,
+                Settings.System.putString(cr, settingName,
                         ContentUris.withAppendedId(uri, rowId).toString());
             }
+            Settings.System.putInt(cr, settingSetIndicatorName(settingName), 1);
         }
 
         private int getFileTypeFromDrm(String path) {
@@ -1083,6 +1103,20 @@
 
     }; // end of anonymous MediaScannerClient instance
 
+    private String settingSetIndicatorName(String base) {
+        return base + "_set";
+    }
+
+    private boolean wasSettingAlreadySet(String name) {
+        ContentResolver cr = mContext.getContentResolver();
+        String indicatorName = settingSetIndicatorName(name);
+        try {
+            return Settings.System.getInt(cr, indicatorName) != 0;
+        } catch (SettingNotFoundException e) {
+            return false;
+        }
+    }
+
     private void prescan(String filePath, boolean prescanFiles) throws RemoteException {
         Cursor c = null;
         String where = null;
@@ -1100,6 +1134,10 @@
             selectionArgs = new String[] { "" };
         }
 
+        mDefaultRingtoneSet = wasSettingAlreadySet(Settings.System.RINGTONE);
+        mDefaultNotificationSet = wasSettingAlreadySet(Settings.System.NOTIFICATION_SOUND);
+        mDefaultAlarmSet = wasSettingAlreadySet(Settings.System.ALARM_ALERT);
+
         // Tell the provider to not delete the file.
         // If the file is truly gone the delete is unnecessary, and we want to avoid
         // accidentally deleting files that are really there (this may happen if the
@@ -1117,7 +1155,6 @@
                 // with CursorWindow positioning.
                 long lastId = Long.MIN_VALUE;
                 Uri limitUri = mFilesUri.buildUpon().appendQueryParameter("limit", "1000").build();
-                mWasEmptyPriorToScan = true;
 
                 while (true) {
                     selectionArgs[0] = "" + lastId;
@@ -1136,7 +1173,6 @@
                     if (num == 0) {
                         break;
                     }
-                    mWasEmptyPriorToScan = false;
                     while (c.moveToNext()) {
                         long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX);
                         String path = c.getString(FILES_PRESCAN_PATH_COLUMN_INDEX);
@@ -1284,7 +1320,7 @@
         }
     }
 
-    private void postscan(String[] directories) throws RemoteException {
+    private void postscan(final String[] directories) throws RemoteException {
 
         // handle playlists last, after we know what media files are on the storage.
         if (mProcessPlaylists) {
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index daa5fa5..abd6f4a 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -92,7 +92,8 @@
         SizedThumbnailBitmap sizedThumbnailBitmap = new SizedThumbnailBitmap();
         Bitmap bitmap = null;
         MediaFileType fileType = MediaFile.getFileType(filePath);
-        if (fileType != null && fileType.fileType == MediaFile.FILE_TYPE_JPEG) {
+        if (fileType != null && (fileType.fileType == MediaFile.FILE_TYPE_JPEG
+                || MediaFile.isRawImageFileType(fileType.fileType))) {
             createThumbnailFromEXIF(filePath, targetSize, maxPixels, sizedThumbnailBitmap);
             bitmap = sizedThumbnailBitmap.mBitmap;
         }
diff --git a/media/java/android/mtp/MtpConstants.java b/media/java/android/mtp/MtpConstants.java
index b2a5a44..bdd8643 100644
--- a/media/java/android/mtp/MtpConstants.java
+++ b/media/java/android/mtp/MtpConstants.java
@@ -202,6 +202,8 @@
     public static final int FORMAT_JP2 = 0x380F;
     /** Format code for JPX files */
     public static final int FORMAT_JPX = 0x3810;
+    /** Format code for DNG files */
+    public static final int FORMAT_DNG = 0x3811;
     /** Format code for firmware files */
     public static final int FORMAT_UNDEFINED_FIRMWARE = 0xB802;
     /** Format code for Windows image files */
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index bc96e2e..29bcc19 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -587,6 +587,7 @@
             MtpConstants.FORMAT_PLS_PLAYLIST,
             MtpConstants.FORMAT_XML_DOCUMENT,
             MtpConstants.FORMAT_FLAC,
+            MtpConstants.FORMAT_DNG,
         };
     }
 
@@ -696,6 +697,7 @@
             case MtpConstants.FORMAT_GIF:
             case MtpConstants.FORMAT_PNG:
             case MtpConstants.FORMAT_BMP:
+            case MtpConstants.FORMAT_DNG:
                 return IMAGE_PROPERTIES;
             default:
                 return FILE_PROPERTIES;
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index d24c5e8..4379a99 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -21,6 +21,8 @@
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.IOException;
 
 /**
@@ -164,12 +166,14 @@
      * of the data and speed of the devices.
      *
      * @param objectHandle handle of the object to read
-     * @param offset Start index of reading range.
-     * @param size Size of reading range.
+     * @param offset Start index of reading range. It must be a non-negative value at most
+     *     0xffffffff.
+     * @param size Size of reading range. It must be a non-negative value at most 0xffffffff. If
+     *     0xffffffff is specified, the method obtains the full bytes of object.
      * @param buffer Array to write data.
      * @return Size of bytes that are actually read.
      */
-    public int getPartialObject(int objectHandle, int offset, int size, byte[] buffer)
+    public long getPartialObject(int objectHandle, long offset, long size, byte[] buffer)
             throws IOException {
         return native_get_partial_object(objectHandle, offset, size, buffer);
     }
@@ -340,8 +344,8 @@
     private native int[] native_get_object_handles(int storageId, int format, int objectHandle);
     private native MtpObjectInfo native_get_object_info(int objectHandle);
     private native byte[] native_get_object(int objectHandle, int objectSize);
-    private native int native_get_partial_object(
-            int objectHandle, int offset, int objectSize, byte[] buffer) throws IOException;
+    private native long native_get_partial_object(
+            int objectHandle, long offset, long objectSize, byte[] buffer) throws IOException;
     private native byte[] native_get_thumbnail(int objectHandle);
     private native boolean native_delete_object(int objectHandle);
     private native long native_get_parent(int objectHandle);
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 79557bc..a326f6f 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -3,6 +3,7 @@
 
 LOCAL_SRC_FILES:= \
     android_media_AmrInputStream.cpp \
+    android_media_ExifInterface.cpp \
     android_media_ImageWriter.cpp \
     android_media_ImageReader.cpp \
     android_media_MediaCrypto.cpp \
@@ -44,6 +45,7 @@
     libusbhost \
     libjhead \
     libexif \
+    libpiex \
     libstagefright_amrnb_common
 
 LOCAL_REQUIRED_MODULES := \
@@ -54,6 +56,7 @@
 
 LOCAL_C_INCLUDES += \
     external/libexif/ \
+    external/piex/ \
     external/tremor/Tremor \
     frameworks/base/core/jni \
     frameworks/base/libs/hwui \
diff --git a/media/jni/android_media_ExifInterface.cpp b/media/jni/android_media_ExifInterface.cpp
new file mode 100644
index 0000000..463c17e
--- /dev/null
+++ b/media/jni/android_media_ExifInterface.cpp
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ExifInterface_JNI"
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/KeyedVector.h>
+
+#include <android_runtime/AndroidRuntime.h>
+
+#include <jni.h>
+#include <JNIHelp.h>
+
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "src/piex_types.h"
+#include "src/piex.h"
+
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+class FileStream : public piex::StreamInterface {
+private:
+    FILE *mFile;
+    size_t mPosition;
+    size_t mSize;
+
+public:
+    FileStream(const String8 filename)
+        : mPosition(0),
+          mSize(0) {
+        mFile = fopen(filename.string(), "r");
+        if (mFile == NULL) {
+            return;
+        }
+        // Get the size.
+        fseek(mFile, 0l, SEEK_END);
+        mSize = ftell(mFile);
+        fseek(mFile, 0l, SEEK_SET);
+    }
+
+    ~FileStream() {
+        if (mFile != NULL) {
+            fclose(mFile);
+            mFile = NULL;
+        }
+    }
+
+    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
+    // provided by the caller, guaranteed to be at least "length" bytes long.
+    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
+    // 'offset' bytes from the start of the stream.
+    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
+    // change the contents of 'data'.
+    piex::Error GetData(
+            const size_t offset, const size_t length, std::uint8_t* data)
+            override {
+        if (mFile == NULL) {
+            return piex::Error::kFail;
+        }
+
+        // Seek first.
+        if (mPosition != offset) {
+            fseek(mFile, offset, SEEK_SET);
+        }
+
+        // Read bytes.
+        size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile);
+        mPosition += size;
+
+        // Handle errors.
+        if (ferror(mFile)) {
+            return piex::Error::kFail;
+        }
+        if (size == 0 && feof(mFile)) {
+            return piex::Error::kFail;
+        }
+        return piex::Error::kOk;
+    }
+
+    bool exists() {
+        return mFile != NULL;
+    }
+
+    size_t size() {
+        return mSize;
+    }
+};
+
+#define FIND_CLASS(var, className) \
+    var = env->FindClass(className); \
+    LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
+    var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
+    LOG_FATAL_IF(! var, "Unable to find method " fieldName);
+
+struct HashMapFields {
+    jmethodID init;
+    jmethodID put;
+};
+
+struct fields_t {
+    HashMapFields hashMap;
+    jclass hashMapClassId;
+};
+
+static fields_t gFields;
+
+static jobject KeyedVectorToHashMap(JNIEnv *env, KeyedVector<String8, String8> const &map) {
+    jclass clazz = gFields.hashMapClassId;
+    jobject hashMap = env->NewObject(clazz, gFields.hashMap.init);
+    for (size_t i = 0; i < map.size(); ++i) {
+        jstring jkey = env->NewStringUTF(map.keyAt(i).string());
+        jstring jvalue = env->NewStringUTF(map.valueAt(i).string());
+        env->CallObjectMethod(hashMap, gFields.hashMap.put, jkey, jvalue);
+        env->DeleteLocalRef(jkey);
+        env->DeleteLocalRef(jvalue);
+    }
+    return hashMap;
+}
+
+extern "C" {
+
+// -------------------------- ExifInterface methods ---------------------------
+
+static void ExifInterface_initRaw(JNIEnv *env) {
+    jclass clazz;
+    FIND_CLASS(clazz, "java/util/HashMap");
+    gFields.hashMapClassId = static_cast<jclass>(env->NewGlobalRef(clazz));
+
+    GET_METHOD_ID(gFields.hashMap.init, clazz, "<init>", "()V");
+    GET_METHOD_ID(gFields.hashMap.put, clazz, "put",
+                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+}
+
+static jobject ExifInterface_getRawMetadata(
+        JNIEnv* env, jclass /* clazz */, jstring jfilename) {
+    const char* filenameChars = env->GetStringUTFChars(jfilename, NULL);
+    if (filenameChars == NULL) {
+        return NULL;
+    }
+    String8 filename(filenameChars);
+    env->ReleaseStringUTFChars(jfilename, filenameChars);
+
+    piex::PreviewImageData image_data;
+    memset(&image_data, 0, sizeof(image_data));
+    std::unique_ptr<FileStream> stream(new FileStream(filename));
+
+    if (!stream.get()->exists()) {
+        // File is not exists.
+        ALOGI("File is not exists: %s", filename.string());
+        return NULL;
+    }
+
+    if (!piex::IsRaw(stream.get())) {
+        // Format not supported.
+        ALOGI("Format not supported: %s", filename.string());
+        return NULL;
+    }
+
+    piex::Error err = piex::GetPreviewImageData(stream.get(), &image_data);
+    if (err != piex::Error::kOk) {
+        // The input data seems to be broken.
+        ALOGI("Raw image not detected: %s (error code: %d)", filename.string(), (int32_t)err);
+        return NULL;
+    }
+
+    if (image_data.thumbnail_offset + image_data.thumbnail_length > stream.get()->size()) {
+        // Corrupted file.
+        ALOGI("Corrupted file: %s", filename.string());
+        return NULL;
+    }
+
+    KeyedVector<String8, String8> map;
+
+    if (image_data.thumbnail_length > 0) {
+        map.add(String8("hasThumbnail"), String8("true"));
+        map.add(String8("thumbnailOffset"), String8::format("%d", image_data.thumbnail_offset));
+        map.add(String8("thumbnailLength"), String8::format("%d", image_data.thumbnail_length));
+    } else {
+        map.add(String8("hasThumbnail"), String8("false"));
+    }
+
+    map.add(
+            String8("Orientation"),
+            String8::format("%u", image_data.exif_orientation));
+    map.add(
+            String8("ImageWidth"),
+            String8::format("%u", image_data.full_width));
+    map.add(
+            String8("ImageLength"),
+            String8::format("%u", image_data.full_height));
+
+    // Current PIEX does not have LightSource information while JPEG version of
+    // EXIFInterface always declares the light source field. For the
+    // compatibility, it provides the default value of the light source field.
+    map.add(String8("LightSource"), String8("0"));
+
+    if (!image_data.maker.empty()) {
+        map.add(String8("Make"), String8(image_data.maker.c_str()));
+    }
+
+    if (!image_data.model.empty()) {
+        map.add(String8("Model"), String8(image_data.model.c_str()));
+    }
+
+    if (!image_data.date_time.empty()) {
+        map.add(String8("DateTime"), String8(image_data.date_time.c_str()));
+    }
+
+    if (image_data.iso) {
+        map.add(
+                String8("ISOSpeedRatings"),
+                String8::format("%u", image_data.iso));
+    }
+
+    if (image_data.exposure_time.numerator != 0
+            && image_data.exposure_time.denominator != 0) {
+        double exposureTime =
+            (double)image_data.exposure_time.numerator
+            / image_data.exposure_time.denominator;
+
+        const char* format;
+        if (exposureTime < 0.01) {
+            format = "%6.4f";
+        } else {
+            format = "%5.3f";
+        }
+        map.add(String8("ExposureTime"), String8::format(format, exposureTime));
+    }
+
+    if (image_data.fnumber.numerator != 0
+            && image_data.fnumber.denominator != 0) {
+        double fnumber =
+            (double)image_data.fnumber.numerator
+            / image_data.fnumber.denominator;
+        map.add(String8("FNumber"), String8::format("%5.3f", fnumber));
+    }
+
+    if (image_data.focal_length.numerator != 0
+            && image_data.focal_length.denominator != 0) {
+        map.add(
+                String8("FocalLength"),
+                String8::format(
+                        "%u/%u",
+                        image_data.focal_length.numerator,
+                        image_data.focal_length.denominator));
+    }
+
+    if (image_data.gps.is_valid) {
+        if (image_data.gps.latitude[0].denominator != 0
+                && image_data.gps.latitude[1].denominator != 0
+                && image_data.gps.latitude[2].denominator != 0) {
+            map.add(
+                    String8("GPSLatitude"),
+                    String8::format(
+                            "%u/%u,%u/%u,%u/%u",
+                            image_data.gps.latitude[0].numerator,
+                            image_data.gps.latitude[0].denominator,
+                            image_data.gps.latitude[1].numerator,
+                            image_data.gps.latitude[1].denominator,
+                            image_data.gps.latitude[2].numerator,
+                            image_data.gps.latitude[2].denominator));
+        }
+
+        if (image_data.gps.latitude_ref) {
+            char str[2];
+            str[0] = image_data.gps.latitude_ref;
+            str[1] = 0;
+            map.add(String8("GPSLatitudeRef"), String8(str));
+        }
+
+        if (image_data.gps.longitude[0].denominator != 0
+                && image_data.gps.longitude[1].denominator != 0
+                && image_data.gps.longitude[2].denominator != 0) {
+            map.add(
+                    String8("GPSLongitude"),
+                    String8::format(
+                            "%u/%u,%u/%u,%u/%u",
+                            image_data.gps.longitude[0].numerator,
+                            image_data.gps.longitude[0].denominator,
+                            image_data.gps.longitude[1].numerator,
+                            image_data.gps.longitude[1].denominator,
+                            image_data.gps.longitude[2].numerator,
+                            image_data.gps.longitude[2].denominator));
+        }
+
+        if (image_data.gps.longitude_ref) {
+            char str[2];
+            str[0] = image_data.gps.longitude_ref;
+            str[1] = 0;
+            map.add(String8("GPSLongitudeRef"), String8(str));
+        }
+
+        if (image_data.gps.altitude.denominator != 0) {
+            map.add(
+                    String8("GPSAltitude"),
+                    String8::format("%u/%u",
+                            image_data.gps.altitude.numerator,
+                            image_data.gps.altitude.denominator));
+
+            map.add(
+                    String8("GPSAltitudeRef"),
+                    String8(image_data.gps.altitude_ref ? "1" : "0"));
+        }
+
+        if (image_data.gps.time_stamp[0].denominator != 0
+                && image_data.gps.time_stamp[1].denominator != 0
+                && image_data.gps.time_stamp[2].denominator != 0) {
+            map.add(
+                    String8("GPSTimeStamp"),
+                    String8::format(
+                            "%2u:%2u:%2u",
+                            image_data.gps.time_stamp[0].numerator
+                            / image_data.gps.time_stamp[0].denominator,
+                            image_data.gps.time_stamp[1].numerator
+                            / image_data.gps.time_stamp[1].denominator,
+                            image_data.gps.time_stamp[2].numerator
+                            / image_data.gps.time_stamp[2].denominator));
+        }
+
+        if (!image_data.gps.date_stamp.empty()) {
+            map.add(
+                    String8("GPSDateStamp"),
+                    String8(image_data.gps.date_stamp.c_str()));
+        }
+    }
+
+    return KeyedVectorToHashMap(env, map);
+}
+
+} // extern "C"
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gMethods[] = {
+    { "initRawNative", "()V", (void *)ExifInterface_initRaw },
+    { "getRawAttributesNative", "(Ljava/lang/String;)Ljava/util/HashMap;",
+      (void*)ExifInterface_getRawMetadata },
+};
+
+int register_android_media_ExifInterface(JNIEnv *env) {
+    return AndroidRuntime::registerNativeMethods(
+            env,
+            "android/media/ExifInterface",
+            gMethods,
+            NELEM(gMethods));
+}
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index be36729..e9d62de 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -1088,6 +1088,7 @@
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
 }
+extern int register_android_media_ExifInterface(JNIEnv *env);
 extern int register_android_media_ImageReader(JNIEnv *env);
 extern int register_android_media_ImageWriter(JNIEnv *env);
 extern int register_android_media_Crypto(JNIEnv *env);
@@ -1219,6 +1220,11 @@
         goto bail;
     }
 
+    if (register_android_media_ExifInterface(env) < 0) {
+        ALOGE("ERROR: ExifInterface native registration failed");
+        goto bail;
+    }
+
     /* success -- return valid version number */
     result = JNI_VERSION_1_4;
 
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 130dfe5..b1b3b62 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -372,12 +372,12 @@
     return nullptr;
 }
 
-static jint
+static jlong
 android_mtp_MtpDevice_get_partial_object(JNIEnv *env,
                                          jobject thiz,
                                          jint objectID,
-                                         jint offset,
-                                         jint size,
+                                         jlong offset,
+                                         jlong size,
                                          jbyteArray array)
 {
     if (!array) {
@@ -385,6 +385,22 @@
         return -1;
     }
 
+    if (offset < 0 || 0xffffffffL < offset) {
+        jniThrowException(
+                env,
+                "java/lang/IllegalArgumentException",
+                "Offset argument must be a 32-bit unsigned integer.");
+        return -1;
+    }
+
+    if (size < 0 || 0xffffffffL < size) {
+        jniThrowException(
+                env,
+                "java/lang/IllegalArgumentException",
+                "Size argument must be a 32-bit unsigned integer.");
+        return -1;
+    }
+
     MtpDevice* const device = get_device_from_object(env, thiz);
     if (!device) {
         jniThrowException(env, "java/io/IOException", "Failed to obtain MtpDevice.");
@@ -393,16 +409,13 @@
 
     JavaArrayWriter writer(env, array);
     uint32_t written_size;
-    bool success = device->readPartialObject(
+    const bool success = device->readPartialObject(
             objectID, offset, size, &written_size, JavaArrayWriter::writeTo, &writer);
     if (!success) {
         jniThrowException(env, "java/io/IOException", "Failed to read data.");
         return -1;
     }
-    // Note: assumption here is that a negative value will be treated as unsigned on the Java
-    //       level.
-    // TODO: Make sure that actually holds.
-    return static_cast<jint>(written_size);
+    return static_cast<jlong>(written_size);
 }
 
 static jbyteArray
@@ -615,7 +628,7 @@
     {"native_get_object_info",  "(I)Landroid/mtp/MtpObjectInfo;",
                                         (void *)android_mtp_MtpDevice_get_object_info},
     {"native_get_object",       "(II)[B",(void *)android_mtp_MtpDevice_get_object},
-    {"native_get_partial_object", "(III[B)I", (void *)android_mtp_MtpDevice_get_partial_object},
+    {"native_get_partial_object", "(IJJ[B)J", (void *)android_mtp_MtpDevice_get_partial_object},
     {"native_get_thumbnail",    "(I)[B",(void *)android_mtp_MtpDevice_get_thumbnail},
     {"native_delete_object",    "(I)Z", (void *)android_mtp_MtpDevice_delete_object},
     {"native_get_parent",       "(I)J", (void *)android_mtp_MtpDevice_get_parent},
diff --git a/packages/BackupRestoreConfirmation/res/values-de/strings.xml b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
index a2e24e7..55940c8 100644
--- a/packages/BackupRestoreConfirmation/res/values-de/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
@@ -18,19 +18,19 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Vollständige Sicherung"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Vollständige Wiederherstellung"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Es wurde eine vollständige Sicherung sämtlicher Daten auf einen verbundenen Desktop-Computer angefordert. Möchten Sie dies zulassen?\n\nWenn Sie die Sicherung nicht selbst angefordert haben, sollten Sie dem Vorgang nicht zustimmen."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Es wurde eine vollständige Sicherung sämtlicher Daten auf einen verbundenen Desktop-Computer angefordert. Möchtest du dies zulassen?\n\nWenn du die Sicherung nicht selbst angefordert hast, solltest du dem Vorgang nicht zustimmen."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Meine Daten sichern"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nicht sichern"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Es wurde eine vollständige Wiederherstellung aller Daten von einem verbundenen Desktop-Computer angefordert. Möchten Sie dies zulassen?\n\nWenn Sie die Wiederherstellung nicht selbst angefordert haben, sollten Sie dem Vorgang nicht zustimmen. Dadurch werden alle zurzeit auf dem Gerät befindlichen Daten ersetzt!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Es wurde eine vollständige Wiederherstellung aller Daten von einem verbundenen Desktop-Computer angefordert. Möchtest du dies zulassen?\n\nWenn du die Wiederherstellung nicht selbst angefordert hast, solltest du dem Vorgang nicht zustimmen. Dadurch werden alle derzeit auf dem Gerät befindlichen Daten ersetzt!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Meine Daten wiederherstellen"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Nicht wiederherstellen"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Geben Sie Ihr aktuelles Sicherungspasswort unten ein:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Geben Sie Ihr Passwort zur Geräteverschlüsselung unten ein."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geben Sie Ihr Passwort zur Geräteverschlüsselung unten ein. Damit wird auch das Sicherungsarchiv verschlüsselt."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Geben Sie ein Passwort für die Verschlüsselung der vollständigen Sicherungsdaten ein. Wenn Sie dieses Feld leer lassen, wird Ihr aktuelles Sicherungspasswort verwendet:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Wenn Sie die gesamten Sicherungsdaten verschlüsseln möchten, geben Sie unten ein Passwort ein:"</string>
-    <string name="backup_enc_password_required" msgid="7889652203371654149">"Da Ihr Gerät verschlüsselt ist, muss auch die Sicherung verschlüsselt werden. Geben Sie unten ein Passwort ein:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Geben Sie das Passwort unten ein, wenn die Daten für die Wiederherstellung verschlüsselt sind:"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Gib dein aktuelles Sicherungspasswort unten ein:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Gib dein Passwort zur Geräteverschlüsselung unten ein."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Gib dein Passwort zur Geräteverschlüsselung unten ein. Damit wird auch das Sicherungsarchiv verschlüsselt."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Gib ein Passwort für die Verschlüsselung der vollständigen Sicherungsdaten ein. Wenn du dieses Feld leer lässt, wird dein aktuelles Sicherungspasswort verwendet:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Wenn du die gesamten Sicherungsdaten verschlüsseln möchtest, gib unten ein Passwort ein:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"Da dein Gerät verschlüsselt ist, muss auch die Sicherung verschlüsselt werden. Gib unten ein Passwort ein:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Gib das Passwort unten ein, wenn die Daten für die Wiederherstellung verschlüsselt sind:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Sicherung wird gestartet..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Sicherung abgeschlossen"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"Wiederherstellung wird gestartet..."</string>
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
index fd2058d..52c9dc8 100644
--- a/packages/CaptivePortalLogin/res/values-de/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-de/strings.xml
@@ -5,7 +5,7 @@
     <string name="action_use_network" msgid="6076184727448466030">"Dieses Netzwerk im Istzustand verwenden"</string>
     <string name="action_do_not_use_network" msgid="4577366536956516683">"Dieses Netzwerk nicht verwenden"</string>
     <string name="action_bar_label" msgid="917235635415966620">"Im Netzwerk anmelden"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Im Netzwerk, zu dem Sie eine Verbindung herstellen möchten, liegen Sicherheitsprobleme vor."</string>
+    <string name="ssl_error_warning" msgid="6653188881418638872">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
     <string name="ssl_error_example" msgid="647898534624078900">"Beispiel: Die Log-in-Seite gehört möglicherweise nicht zur angezeigten Organisation."</string>
     <string name="ssl_error_continue" msgid="6492718244923937110">"Trotzdem in einem Browser fortfahren"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/drawable/ic_root_home.xml b/packages/DocumentsUI/res/drawable/ic_root_home.xml
index 0a258ac..696ee05 100644
--- a/packages/DocumentsUI/res/drawable/ic_root_home.xml
+++ b/packages/DocumentsUI/res/drawable/ic_root_home.xml
@@ -1,15 +1,24 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
+<!--
+Copyright (C) 2015 The Android Open Source Project
 
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:fillColor="#000000"
-        android:pathData="M20 6h-8l-2-2H4c-1.1 0-1.99 .9 -1.99 2L2 18c0 1.1 .9 2 2 2h16c1.1 0 2-.9
-2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4
-8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z" />
-    <path
-        android:pathData="M0 0h24v24H0z" />
+        android:fillColor="#FF000000"
+        android:pathData="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
 </vector>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 180a48e..0fb8daf 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -38,24 +38,21 @@
 import android.provider.DocumentsContract.Root;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.Nullable;
-import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
-import android.widget.SearchView;
-import android.widget.SearchView.OnQueryTextListener;
 import android.widget.TextView;
 
 import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.SearchManager;
+import com.android.documentsui.SearchManager.SearchManagerListener;
 import com.android.documentsui.dirlist.DirectoryFragment;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
@@ -72,7 +69,7 @@
 import java.util.List;
 import java.util.concurrent.Executor;
 
-public abstract class BaseActivity extends Activity {
+public abstract class BaseActivity extends Activity implements SearchManagerListener {
 
     static final String EXTRA_STATE = "state";
 
@@ -91,7 +88,7 @@
     public abstract void onDocumentsPicked(List<DocumentInfo> docs);
 
     abstract void onTaskFinished(Uri... uris);
-    abstract void onDirectoryChanged(int anim);
+    abstract void refreshDirectory(int anim);
     abstract void updateActionBar();
     abstract void saveStackBlocking();
     abstract State buildState();
@@ -121,7 +118,7 @@
                     }
                 });
         mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
-        mSearchManager = new SearchManager();
+        mSearchManager = new SearchManager(this);
 
         // Base classes must update result in their onCreate.
         setResult(Activity.RESULT_CANCELED);
@@ -176,6 +173,12 @@
         return true;
     }
 
+    @Override
+    protected void onDestroy() {
+        mRoots.setOnCacheUpdateListener(null);
+        super.onDestroy();
+    }
+
     State buildDefaultState() {
         State state = new State();
 
@@ -207,7 +210,7 @@
         // Otherwise we delegate loading data from disk to a task
         // to ensure a responsive ui.
         if (mRoots.isRecentsRoot(root)) {
-            onCurrentDirectoryChanged(ANIM_SIDE);
+            refreshCurrentRootAndDirectory(ANIM_SIDE);
         } else {
             new PickRootTask(root, true).executeOnExecutor(getExecutorForCurrentDirectory());
         }
@@ -313,19 +316,19 @@
     void openContainerDocument(DocumentInfo doc) {
         checkArgument(doc.isContainer());
         mState.pushDocument(doc);
-        onCurrentDirectoryChanged(ANIM_DOWN);
+        refreshCurrentRootAndDirectory(ANIM_DOWN);
     }
 
     /**
-     * Call this when directory changes. Prior to root fragment update
-     * the (abstract) directoryChanged method will be called.
+     * Refreshes the content of the director and the menu/action bar.
+     * The current directory name and selection will get updated.
      * @param anim
      */
-    // TODO: Refactor the usage of the method - now it is called not only when the directory
-    // changed, but also to refresh the content of the directory while searching
-    final void onCurrentDirectoryChanged(int anim) {
+    final void refreshCurrentRootAndDirectory(int anim) {
+        mSearchManager.cancelSearch();
+
         mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN);
-        onDirectoryChanged(anim);
+        refreshDirectory(anim);
 
         final RootsFragment roots = RootsFragment.get(getFragmentManager());
         if (roots != null) {
@@ -334,10 +337,28 @@
 
         updateActionBar();
 
-        // Prevents searchView from being recreated while searching
-        if (!mSearchManager.isSearching()) {
-            invalidateOptionsMenu();
-        }
+        invalidateOptionsMenu();
+    }
+
+    /**
+     * Called when search results changed.
+     * Refreshes the content of the directory. It doesn't refresh elements on the action bar.
+     * e.g. The current directory name displayed on the action bar won't get updated.
+     */
+    @Override
+    public void onSearchChanged() {
+        mDirectoryContainer.setDrawDisappearingFirst(false);
+        refreshDirectory(ANIM_NONE);
+    }
+
+    /**
+     * Called when search query changed.
+     * Updates the state object.
+     * @param query - New query
+     */
+    @Override
+    public void onSearchQueryChanged(String query) {
+        mState.currentSearch = query;
     }
 
     final List<String> getExcludedAuthorities() {
@@ -473,7 +494,7 @@
             mDrawer.setOpen(false);
         } else if (size > 1) {
             mState.stack.pop();
-            onCurrentDirectoryChanged(ANIM_UP);
+            refreshCurrentRootAndDirectory(ANIM_UP);
         } else {
             super.onBackPressed();
         }
@@ -484,7 +505,7 @@
             // Update the restored stack to ensure we have freshest data
             stack.updateDocuments(getContentResolver());
             mState.setStack(stack);
-            onCurrentDirectoryChanged(ANIM_SIDE);
+            refreshCurrentRootAndDirectory(ANIM_SIDE);
 
         } catch (FileNotFoundException e) {
             Log.w(mTag, "Failed to restore stack: " + e);
@@ -518,7 +539,7 @@
 
         @Override
         protected void onPostExecute(DocumentInfo result) {
-            if (result != null) {
+            if (result != null && !isDestroyed()) {
                 openContainerDocument(result);
             }
         }
@@ -573,7 +594,7 @@
         protected void onPostExecute(Void result) {
             if (isDestroyed()) return;
             mState.restored = true;
-            onCurrentDirectoryChanged(ANIM_NONE);
+            refreshCurrentRootAndDirectory(ANIM_NONE);
             onStackRestored(mRestoredStack, mExternal);
         }
     }
@@ -630,7 +651,7 @@
 
         @Override
         protected void onPostExecute(RootInfo homeRoot) {
-            if (homeRoot != null && mHome != null) {
+            if (homeRoot != null && mHome != null && !isDestroyed()) {
                 // Clear entire backstack and start in new root
                 mState.onRootChanged(homeRoot);
                 mSearchManager.update(homeRoot);
@@ -653,7 +674,7 @@
             while (mState.stack.size() > position + 1) {
                 mState.popDocument();
             }
-            onCurrentDirectoryChanged(ANIM_UP);
+            refreshCurrentRootAndDirectory(ANIM_UP);
         }
 
         @Override
@@ -726,170 +747,6 @@
     }
 
     /**
-     * Facade over the various search parts in the menu.
-     */
-    final class SearchManager implements
-            SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener,
-            DocumentsToolBar.OnActionViewCollapsedListener {
-
-        private boolean mSearchExpanded;
-        private boolean mIgnoreNextClose;
-        private boolean mIgnoreNextCollapse;
-
-        private DocumentsToolBar mActionBar;
-        private MenuItem mMenu;
-        private SearchView mView;
-
-        public void install(DocumentsToolBar actionBar) {
-            assert(mActionBar == null);
-            mActionBar = actionBar;
-            mMenu = actionBar.getSearchMenu();
-            mView = (SearchView) mMenu.getActionView();
-
-            mActionBar.setOnActionViewCollapsedListener(this);
-            mView.setOnQueryTextListener(this);
-            mView.setOnCloseListener(this);
-            mView.setOnSearchClickListener(this);
-            mView.setOnQueryTextFocusChangeListener(this);
-        }
-
-        /**
-         * @param root Info about the current directory.
-         */
-        void update(RootInfo root) {
-            if (mMenu == null) {
-                Log.d(mTag, "update called before Search MenuItem installed.");
-                return;
-            }
-
-            if (mState.currentSearch != null) {
-                mMenu.expandActionView();
-
-                mView.setIconified(false);
-                mView.clearFocus();
-                mView.setQuery(mState.currentSearch, false);
-            } else {
-                mView.clearFocus();
-                if (!mView.isIconified()) {
-                    mIgnoreNextClose = true;
-                    mView.setIconified(true);
-                }
-
-                if (mMenu.isActionViewExpanded()) {
-                    mIgnoreNextCollapse = true;
-                    mMenu.collapseActionView();
-                }
-            }
-
-            showMenu(root != null
-                    && ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0));
-        }
-
-        void showMenu(boolean visible) {
-            if (mMenu == null) {
-                Log.d(mTag, "showMenu called before Search MenuItem installed.");
-                return;
-            }
-
-            mMenu.setVisible(visible);
-            if (!visible) {
-                mState.currentSearch = null;
-            }
-        }
-
-        /**
-         * Cancels current search operation.
-         * @return True if it cancels search. False if it does not operate
-         *     search currently.
-         */
-        boolean cancelSearch() {
-            if (isExpanded() || isSearching()) {
-                // If the query string is not empty search view won't get iconified
-                mView.setQuery("", false);
-                mView.setIconified(true);
-                return true;
-            }
-            return false;
-        }
-
-        boolean isSearching() {
-            return mState.currentSearch != null;
-        }
-
-        boolean isExpanded() {
-            return mSearchExpanded;
-        }
-
-        /**
-         * Clears the search.
-         * @return True if the default behavior of clearing/dismissing SearchView should be
-         *      overridden. False otherwise.
-         */
-        @Override
-        public boolean onClose() {
-            mSearchExpanded = false;
-            if (mIgnoreNextClose) {
-                mIgnoreNextClose = false;
-                return false;
-            }
-
-            mView.setBackgroundColor(
-                    getResources().getColor(android.R.color.transparent, null));
-
-            // Refresh the directory if a search was done
-            if(mState.currentSearch != null) {
-                mState.currentSearch = null;
-                onCurrentDirectoryChanged(ANIM_NONE);
-            }
-
-            return false;
-        }
-
-        /**
-         * Sets mSearchExpanded.
-         * Called when search icon is clicked to start search.
-         * Used to detect when the view expanded instead of onMenuItemActionExpand, because
-         * SearchView has showAsAction set to always and onMenuItemAction* methods are not called.
-         */
-        @Override
-        public void onClick (View v) {
-            mSearchExpanded = true;
-            mView.setBackgroundColor(
-                    getResources().getColor(R.color.menu_search_background, null));
-        }
-
-        @Override
-        public boolean onQueryTextSubmit(String query) {
-            mState.currentSearch = query;
-            mView.clearFocus();
-            onCurrentDirectoryChanged(ANIM_NONE);
-            return true;
-        }
-
-        @Override
-        public boolean onQueryTextChange(String newText) {
-            return false;
-        }
-
-        @Override
-        public void onFocusChange(View v, boolean hasFocus) {
-            if(!hasFocus) {
-                if(mState.currentSearch == null) {
-                    mView.setIconified(true);
-                }
-                else if(TextUtils.isEmpty(mView.getQuery())) {
-                    cancelSearch();
-                }
-            }
-        }
-
-        @Override
-        public void onActionViewCollapsed() {
-            updateActionBar();
-        }
-    }
-
-    /**
      * Interface providing access to current view of documents
      * even when all documents are not homed to the same parent.
      */
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 223af89..6dcd472 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -120,7 +120,7 @@
             setTitle("");
             new RestoreStackTask().execute();
         } else {
-            onCurrentDirectoryChanged(ANIM_NONE);
+            refreshCurrentRootAndDirectory(ANIM_NONE);
         }
     }
 
@@ -332,7 +332,7 @@
     }
 
     @Override
-    void onDirectoryChanged(int anim) {
+    void refreshDirectory(int anim) {
         final FragmentManager fm = getFragmentManager();
         final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
@@ -353,12 +353,12 @@
                 mState.derivedMode = mState.userMode;
             }
         } else {
-            if (mState.currentSearch != null) {
+            if (mSearchManager.isSearching()) {
                 // Ongoing search
                 DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
             } else {
                 // Normal boring directory
-                DirectoryFragment.showNormal(fm, root, cwd, anim);
+                DirectoryFragment.showDirectory(fm, root, cwd, anim);
             }
         }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
index b806ced..3302da9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
@@ -92,7 +92,7 @@
             final Uri rootUri = getIntent().getData();
             new RestoreRootTask(rootUri).executeOnExecutor(getExecutorForCurrentDirectory());
         } else {
-            onCurrentDirectoryChanged(ANIM_NONE);
+            refreshCurrentRootAndDirectory(ANIM_NONE);
         }
     }
 
@@ -164,7 +164,7 @@
     }
 
     @Override
-    void onDirectoryChanged(int anim) {
+    void refreshDirectory(int anim) {
         final FragmentManager fm = getFragmentManager();
         final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
@@ -178,7 +178,7 @@
             DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
         } else {
             // Normal boring directory
-            DirectoryFragment.showNormal(fm, root, cwd, anim);
+            DirectoryFragment.showDirectory(fm, root, cwd, anim);
         }
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 0bd09f6..58537ee 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -95,7 +95,7 @@
 
         if (mState.restored) {
             if (DEBUG) Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
-            onCurrentDirectoryChanged(ANIM_NONE);
+            refreshCurrentRootAndDirectory(ANIM_NONE);
         } else if (!mState.stack.isEmpty()) {
             // If a non-empty stack is present in our state it was read (presumably)
             // from EXTRA_STACK intent extra. In this case, we'll skip other means of
@@ -106,7 +106,7 @@
             // don't specify a real content target.
             if (DEBUG) Log.d(TAG, "Launching with non-empty stack.");
             checkState(uri == null || LauncherActivity.isLaunchUri(uri));
-            onCurrentDirectoryChanged(ANIM_NONE);
+            refreshCurrentRootAndDirectory(ANIM_NONE);
         } else if (DocumentsContract.isRootUri(this, uri)) {
             if (DEBUG) Log.d(TAG, "Launching with root URI.");
             // If we've got a specific root to display, restore that root using a dedicated
@@ -288,7 +288,7 @@
     }
 
     @Override
-    void onDirectoryChanged(int anim) {
+    void refreshDirectory(int anim) {
         final FragmentManager fm = getFragmentManager();
         final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
@@ -307,7 +307,7 @@
                 DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
             } else {
                 // Normal boring directory
-                DirectoryFragment.showNormal(fm, root, cwd, anim);
+                DirectoryFragment.showDirectory(fm, root, cwd, anim);
             }
         }
     }
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/SearchManager.java b/packages/DocumentsUI/src/com/android/documentsui/SearchManager.java
new file mode 100644
index 0000000..fb585a6
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/SearchManager.java
@@ -0,0 +1,210 @@
+/*
+ * 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 com.android.documentsui;
+
+import android.provider.DocumentsContract.Root;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.widget.SearchView;
+import android.widget.SearchView.OnQueryTextListener;
+
+import com.android.documentsui.model.RootInfo;
+
+/**
+ * Manages searching UI behavior.
+ */
+final class SearchManager implements
+        SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener {
+
+    public interface SearchManagerListener {
+        void onSearchChanged();
+
+        void onSearchQueryChanged(String query);
+    }
+
+    public static final String TAG = "SearchManger";
+
+    private SearchManagerListener mListener;
+    private String currentSearch;
+    private boolean mSearchExpanded;
+    private boolean mIgnoreNextClose;
+
+    private DocumentsToolBar mActionBar;
+    private MenuItem mMenu;
+    private SearchView mView;
+
+    public SearchManager(SearchManagerListener listener) {
+        mListener = listener;
+    }
+
+    public void setSearchMangerListener(SearchManagerListener listener) {
+        mListener = listener;
+    }
+
+    public void install(DocumentsToolBar actionBar) {
+        assert (mActionBar == null);
+        mActionBar = actionBar;
+        mMenu = actionBar.getSearchMenu();
+        mView = (SearchView) mMenu.getActionView();
+
+        mView.setOnQueryTextListener(this);
+        mView.setOnCloseListener(this);
+        mView.setOnSearchClickListener(this);
+        mView.setOnQueryTextFocusChangeListener(this);
+    }
+
+    /**
+     * @param root Info about the current directory.
+     */
+    void update(RootInfo root) {
+        if (mMenu == null) {
+            Log.d(TAG, "update called before Search MenuItem installed.");
+            return;
+        }
+
+        if (currentSearch != null) {
+            mMenu.expandActionView();
+
+            mView.setIconified(false);
+            mView.clearFocus();
+            mView.setQuery(currentSearch, false);
+        } else {
+            mView.clearFocus();
+            if (!mView.isIconified()) {
+                mIgnoreNextClose = true;
+                mView.setIconified(true);
+            }
+
+            if (mMenu.isActionViewExpanded()) {
+                mMenu.collapseActionView();
+            }
+        }
+
+        showMenu(root != null
+                && ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0));
+    }
+
+    void showMenu(boolean visible) {
+        if (mMenu == null) {
+            Log.d(TAG, "showMenu called before Search MenuItem installed.");
+            return;
+        }
+
+        mMenu.setVisible(visible);
+        if (!visible) {
+            currentSearch = null;
+            if (mListener != null) {
+                mListener.onSearchQueryChanged(currentSearch);
+            }
+        }
+    }
+
+    /**
+     * Cancels current search operation. Triggers clearing and collapsing the SearchView.
+     *
+     * @return True if it cancels search. False if it does not operate search currently.
+     */
+    boolean cancelSearch() {
+        if (isExpanded() || isSearching()) {
+            // If the query string is not empty search view won't get iconified
+            mView.setQuery("", false);
+            // Causes calling onClose(). onClose() is triggering directory content update.
+            mView.setIconified(true);
+            return true;
+        }
+        return false;
+    }
+
+    boolean isSearching() {
+        return currentSearch != null;
+    }
+
+    boolean isExpanded() {
+        return mSearchExpanded;
+    }
+
+    /**
+     * Clears the search. Clears the SearchView background color. Triggers refreshing of the
+     * directory content.
+     * @return True if the default behavior of clearing/dismissing SearchView should be overridden.
+     *         False otherwise.
+     */
+    @Override
+    public boolean onClose() {
+        mSearchExpanded = false;
+        if (mIgnoreNextClose) {
+            mIgnoreNextClose = false;
+            return false;
+        }
+
+        mView.setBackgroundColor(
+                mView.getResources().getColor(android.R.color.transparent, null));
+
+        // Refresh the directory if a search was done
+        if (currentSearch != null) {
+            currentSearch = null;
+            if (mListener != null) {
+                mListener.onSearchQueryChanged(currentSearch);
+                mListener.onSearchChanged();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Sets mSearchExpanded. Called when search icon is clicked to start search. Used to detect when
+     * the view expanded instead of onMenuItemActionExpand, because SearchView has showAsAction set
+     * to always and onMenuItemAction* methods are not called.
+     */
+    @Override
+    public void onClick(View v) {
+        mSearchExpanded = true;
+        mView.setBackgroundColor(
+                mView.getResources().getColor(R.color.menu_search_background, null));
+    }
+
+    @Override
+    public boolean onQueryTextSubmit(String query) {
+        currentSearch = query;
+        mView.clearFocus();
+        if (mListener != null) {
+            mListener.onSearchQueryChanged(currentSearch);
+            mListener.onSearchChanged();
+        }
+        return true;
+    }
+
+    @Override
+    public void onFocusChange(View v, boolean hasFocus) {
+        if (!hasFocus) {
+            if (currentSearch == null) {
+                mView.setIconified(true);
+            } else if (TextUtils.isEmpty(mView.getQuery())) {
+                cancelSearch();
+            }
+        }
+    }
+
+    @Override
+    public boolean onQueryTextChange(String newText) {
+        return false;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 22e81c6..580e2d8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -163,7 +163,7 @@
     private MessageBar mMessageBar;
     private View mProgressBar;
 
-    public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
+    public static void showDirectory(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
         show(fm, TYPE_NORMAL, root, doc, null, anim);
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
index 8f89b4e..b1932b8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
@@ -17,6 +17,10 @@
 package com.android.documentsui.services;
 
 import static android.os.SystemClock.elapsedRealtime;
+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.DocumentsApplication.acquireUnstableProviderOrThrow;
 import static com.android.documentsui.Shared.DEBUG;
 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
@@ -44,6 +48,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;
 
@@ -80,9 +85,22 @@
      *
      * @param srcs List of files to be copied.
      */
-    CopyJob(Context serviceContext, Context appContext, Listener listener,
+    CopyJob(Context service, Context appContext, Listener listener,
             String id, DocumentStack destination, List<DocumentInfo> srcs) {
-        super(OPERATION_COPY, serviceContext, appContext, listener, id, destination);
+        super(service, appContext, listener, OPERATION_COPY, id, destination);
+
+        checkArgument(!srcs.isEmpty());
+        this.mSrcFiles = 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.mSrcFiles = srcs;
@@ -91,15 +109,15 @@
     @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 +131,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,7 +182,7 @@
     }
 
     @Override
-    void run(FileOperationService service) throws RemoteException {
+    void start() throws RemoteException {
         mStartTime = elapsedRealtime();
 
         // Acquire content providers.
@@ -186,16 +204,14 @@
 
             // 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);
         }
@@ -219,7 +235,6 @@
      *
      * @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
      */
@@ -228,15 +243,17 @@
         // 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,
                         dstDirInfo.derivedUri) == null) {
-                    onFileFailed(srcInfo);
+                    onFileFailed(srcInfo,
+                            "Provider side copy failed for documents: " + srcInfo.derivedUri + ".");
+                    return false;
                 }
-                return false;
+                return true;
             }
         }
 
@@ -249,6 +266,7 @@
         final String dstMimeType;
         final String dstDisplayName;
 
+        if (DEBUG) Log.d(TAG, "Doing byte copy of document: " + srcInfo);
         // 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()) {
@@ -261,9 +279,7 @@
                 dstDisplayName = srcInfo.displayName +
                         (extension != null ? "." + extension : srcInfo.displayName);
             } else {
-                // The virtual file is not available as any alternative streamable format.
-                // TODO: Log failures.
-                onFileFailed(srcInfo);
+                onFileFailed(srcInfo, "Cannot copy virtual file. No streamable formats available.");
                 return false;
             }
         } else {
@@ -277,7 +293,9 @@
                 dstDirInfo.derivedUri, dstMimeType, dstDisplayName);
         if (dstUri == null) {
             // If this is a directory, the entire subdir will not be copied over.
-            onFileFailed(srcInfo);
+            onFileFailed(srcInfo,
+                    "Couldn't create destination document " + dstDisplayName
+                    + " in directory " + dstDirInfo.displayName + ".");
             return false;
         }
 
@@ -285,7 +303,8 @@
         try {
             dstInfo = DocumentInfo.fromUri(getContentResolver(), dstUri);
         } catch (FileNotFoundException e) {
-            onFileFailed(srcInfo);
+            onFileFailed(srcInfo,
+                    "Could not load DocumentInfo for newly created file: " + dstUri + ".");
             return false;
         }
 
@@ -327,7 +346,7 @@
                     srcDirInfo.documentId);
             cursor = srcClient.query(queryUri, queryColumns, null, null, null);
             DocumentInfo srcInfo;
-            while (cursor.moveToNext()) {
+            while (cursor.moveToNext() && !isCanceled()) {
                 srcInfo = DocumentInfo.fromCursor(cursor, srcDirInfo.authority);
                 success &= processDocument(srcInfo, dstDirInfo);
             }
@@ -374,7 +393,7 @@
             dstFile = dstClient.openFile(dstInfo.derivedUri, "w", canceller);
             dst = new ParcelFileDescriptor.AutoCloseOutputStream(dstFile);
 
-            byte[] buffer = new byte[8192];
+            byte[] buffer = new byte[32 * 1024];
             int len;
             while ((len = src.read(buffer)) != -1) {
                 if (isCanceled()) {
@@ -389,7 +408,8 @@
             srcFile.checkError();
         } catch (IOException e) {
             success = false;
-            onFileFailed(srcInfo);
+            onFileFailed(srcInfo, "Exception thrown while copying from "
+                    + srcInfo.derivedUri + " to " + dstInfo.derivedUri + ".");
 
             if (dstFile != null) {
                 try {
@@ -405,7 +425,7 @@
         }
 
         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);
@@ -452,8 +472,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 +487,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 {
@@ -497,9 +516,13 @@
     boolean isDescendentOf(DocumentInfo doc, DocumentInfo parentDoc)
             throws RemoteException {
         if (parentDoc.isDirectory() && doc.authority.equals(parentDoc.authority)) {
-            return DocumentsContract.isChildDocument(
-                    dstClient, doc.derivedUri, parentDoc.derivedUri);
+            return isChildDocument(dstClient, doc.derivedUri, parentDoc.derivedUri);
         }
         return false;
     }
-}
\ No newline at end of file
+
+    private void onFileFailed(DocumentInfo file, String msg) {
+        Log.w(TAG, msg);
+        onFileFailed(file);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
index 6d87ecf..1df20ac 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
@@ -16,36 +16,47 @@
 
 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;
 import android.util.Log;
 
 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
+
     public static final String TAG = "FileOperationService";
+    private static final int POOL_SIZE = 2;  // "pool size", not *max* "pool size".
 
     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 +79,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 mLastStarted;
 
     @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 +111,50 @@
     }
 
     @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);
-        }
-    }
-
-    @Override
-    protected void onHandleIntent(Intent intent) {
-        if (DEBUG) Log.d(TAG, "onHandleIntent: " + intent);
+    public int onStartCommand(Intent intent, int flags, int startTime) {
+        // 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, startTime, 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 startTime, String jobId, int operationType) {
+        if (DEBUG) Log.d(TAG, "onStartCommand: " + jobId + " with start time " + startTime);
 
-        ArrayList<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
-        DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
+        // Track start time so we can stop the service once we're out of work to do.
+        mLastStarted = startTime;
 
-        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);
 
-            deleteJob(job);
-            if (DEBUG) Log.d(TAG, "Done cleaning up");
+            job = createJob(operationType, jobId, srcs, stack);
+
+            mWakeLock.acquire();
         }
+
+        checkState(job != null);
+        int delay = intent.getIntExtra(EXTRA_DELAY, DEFAULT_DELAY);
+        checkArgument(delay <= MAX_DELAY);
+        ScheduledFuture<?> future = executor.schedule(job, delay, TimeUnit.MILLISECONDS);
+        mRunning.put(jobId, new JobRecord(job, future));
     }
 
     /**
@@ -166,12 +166,25 @@
         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
@@ -179,24 +192,23 @@
         // 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);
+
+        // TODO: Guarantee the job is being finalized
     }
 
-    public static String createJobId() {
-        return String.valueOf(elapsedRealtime());
-    }
+    @GuardedBy("mRunning")
+    private Job createJob(
+            @OpType int operationType, String id, List<DocumentInfo> srcs, DocumentStack stack) {
 
-    Job createJob(
-            @OpType int operationType, String id, ArrayList<DocumentInfo> srcs,
-            DocumentStack stack) {
+        checkArgument(!mRunning.containsKey(id));
 
-        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();
@@ -204,42 +216,90 @@
                 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.
+     */
+    private void shutdown() {
+        if (DEBUG) Log.d(TAG, "Shutting down. Last start time: " + mLastStarted);
+        mWakeLock.release();
+        mWakeLock = null;
+        boolean gonnaStop = stopSelfResult(mLastStarted);
+        if (DEBUG) Log.d(TAG, "Stopping service: " + gonnaStop);
+        if (!gonnaStop) {
+            Log.w(TAG, "Service should be stopping, but reports otherwise.");
+        }
+        // Sadly "gonnaStop" is always false in tests, so we can't guard executor shutdown.
+        List<Runnable> unfinished = executor.shutdownNow();
+        checkState(unfinished.isEmpty());
+    }
+
+    @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, 0, 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, 0);
+
+        synchronized (mRunning) {
+            deleteJob(job);
+        }
     }
 
     @Override
     public void onProgress(CopyJob job) {
-        if (DEBUG) Log.d(TAG, "On copy progress...");
+        if (DEBUG) Log.d(TAG, "onProgress: " + job.id);
         mNotificationManager.notify(job.id, 0, 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, 0, 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..0f1730a3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
@@ -16,6 +16,7 @@
 
 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;
@@ -29,6 +30,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;
@@ -52,6 +54,10 @@
 
     private FileOperations() {}
 
+    public static String createJobId() {
+        return String.valueOf(elapsedRealtime());
+    }
+
     /**
      * Tries to start the activity. Returns the job id.
      */
@@ -78,7 +84,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 +103,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 +126,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,13 +149,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.
      * @return Id of the job.
      */
     public static String delete(
             Activity activity, List<DocumentInfo> srcDocs, DocumentStack location) {
-        String jobId = FileOperationService.createJobId();
+        String jobId = createJobId();
         if (DEBUG) Log.d(TAG, "Initiating 'delete' operation id: " + jobId);
 
         Intent intent = createBaseIntent(OPERATION_DELETE, activity, jobId, srcDocs, location);
@@ -162,15 +168,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));
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
index 5c37a87..c7939eb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
@@ -16,6 +16,12 @@
 
 package com.android.documentsui.services;
 
+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;
 
@@ -39,14 +45,19 @@
 import com.android.documentsui.services.FileOperationService.OpType;
 
 import java.util.ArrayList;
+import java.util.List;
 
-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;
+    final Context service;
     final Context appContext;
     final Listener listener;
 
-    final @OpType int mOpType;
+    final @OpType int operationType;
     final String id;
     final DocumentStack stack;
 
@@ -58,10 +69,9 @@
     /**
      * 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 +80,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,13 +96,31 @@
         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;
+
+    // Service will call this when it is done with the job.
+    abstract void cleanup();
+
     abstract Notification getSetupNotification();
     // TODO: Progress notification for deletes.
     // abstract Notification getProgressNotification(long bytesCopied);
@@ -106,7 +135,7 @@
     }
 
     final ContentResolver getContentResolver() {
-        return serviceContext.getContentResolver();
+        return service.getContentResolver();
     }
 
     void onFileFailed(DocumentInfo file) {
@@ -125,15 +154,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 +176,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 +190,7 @@
                 actionIcon,
                 actionTitle,
                 PendingIntent.getService(
-                        serviceContext,
+                        service,
                         0,
                         cancelIntent,
                         PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT));
@@ -173,21 +202,44 @@
      * 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;
     }
 
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * 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..f46f234 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
@@ -16,6 +16,8 @@
 
 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;
@@ -43,28 +45,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 +75,41 @@
                 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 {
 
-        // 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);
+                    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(srcInfo, dstDirInfo);
 
-        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() && deleteSrcDocument(srcInfo);
+    }
+
+    private boolean deleteSrcDocument(DocumentInfo srcInfo) {
+        // 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 success;
+        return true;  // victory dance!
     }
 }
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/SearchViewUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
new file mode 100644
index 0000000..1b8bd4e
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+import static com.android.documentsui.StubProvider.ROOT_1_ID;
+
+import android.app.Instrumentation;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.Until;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.documentsui.model.RootInfo;
+
+@LargeTest
+public class SearchViewUiTest extends InstrumentationTestCase {
+
+    private static final int TIMEOUT = 5000;
+    private static final String TAG = "SearchViewUiTest";
+    private static final String TARGET_PKG = "com.android.documentsui";
+    private static final String LAUNCHER_PKG = "com.android.launcher";
+
+    private UiBot mBot;
+    private UiDevice mDevice;
+    private Context mContext;
+    private ContentResolver mResolver;
+    private DocumentsProviderHelper mDocsHelper;
+    private ContentProviderClient mClient;
+    private RootInfo mRoot_0;
+    private RootInfo mRoot_1;
+
+    private UiObject mSearchView;
+    private UiObject mSearchTextField;
+    private UiObject mDocsList;
+    private UiObject mMessageTextView;
+    private UiObject mSearchIcon;
+
+    public void setUp() throws Exception {
+        // Initialize UiDevice instance.
+        Instrumentation instrumentation = getInstrumentation();
+
+        mDevice = UiDevice.getInstance(instrumentation);
+
+        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
+
+        // Start from the home screen.
+        mDevice.pressHome();
+        mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), TIMEOUT);
+
+        // NOTE: Must be the "target" context, else security checks in content provider will fail.
+        mContext = instrumentation.getTargetContext();
+        mResolver = mContext.getContentResolver();
+
+        mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
+        mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);
+
+        // Launch app.
+        Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(TARGET_PKG);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        mContext.startActivity(intent);
+        // Wait for the app to appear.
+        mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), TIMEOUT);
+        mDevice.waitForIdle();
+
+        mBot = new UiBot(mDevice, TIMEOUT);
+
+        resetStorage(); // Just incase a test failed and tearDown didn't happen.
+
+        initUiObjects();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mDevice.pressBack();
+        resetStorage();
+        mClient.release();
+    }
+
+    private void resetStorage() throws RemoteException {
+        mClient.call("clear", null, null);
+        // TODO: Would be nice to have an event to wait on here.
+        mDevice.waitForIdle();
+    }
+
+    private void initTestFiles() throws RemoteException {
+        mRoot_0 = mDocsHelper.getRoot(ROOT_0_ID);
+        mRoot_1 = mDocsHelper.getRoot(ROOT_1_ID);
+
+        mDocsHelper.createDocument(mRoot_0, "text/plain", "file10.log");
+        mDocsHelper.createDocument(mRoot_0, "image/png", "file1.png");
+        mDocsHelper.createDocument(mRoot_0, "text/csv", "file2.csv");
+
+        mDocsHelper.createDocument(mRoot_1, "text/plain", "anotherFile0.log");
+        mDocsHelper.createDocument(mRoot_1, "text/plain", "poodles.text");
+    }
+
+    private void initUiObjects() {
+        mSearchView = mBot.findSearchView();
+        mSearchTextField = mBot.findSearchViewTextField();
+        mDocsList = mBot.findDocumentsList();
+        mMessageTextView = mBot.findMessageTextView();
+        mSearchIcon = mBot.findSearchViewIcon();
+    }
+
+    public void testSearchViewExpandsOnClick() throws Exception {
+        assertTrue(mSearchIcon.exists());
+        assertFalse(mSearchTextField.exists());
+
+        mSearchView.click();
+
+        assertTrue(mSearchTextField.exists());
+        assertTrue(mSearchTextField.isFocused());
+        assertFalse(mSearchIcon.exists());
+    }
+
+    public void testSearchViewCollapsesOnBack() throws Exception {
+        assertTrue(mSearchIcon.exists());
+        assertFalse(mSearchTextField.exists());
+
+        mSearchView.click();
+
+        mDevice.pressBack();
+
+        assertTrue(mSearchIcon.exists());
+        assertFalse(mSearchTextField.exists());
+    }
+
+    public void testSearchViewClearsTextOnBack() throws Exception {
+        assertTrue(mSearchIcon.exists());
+        assertFalse(mSearchTextField.exists());
+
+        String query = "file2";
+        mSearchView.click();
+        mSearchTextField.setText(query);
+
+        assertSearchTextField(true, query);
+
+        mDevice.pressBack();
+
+        assertTrue(mSearchIcon.exists());
+        assertFalse(mSearchTextField.exists());
+    }
+
+    public void testSearchFound() throws Exception {
+        initTestFiles();
+
+        mBot.openRoot(ROOT_0_ID);
+
+        assertDefaultTestDir0();
+
+        String query = "file1";
+        mSearchView.click();
+        mSearchTextField.setText(query);
+
+        assertTrue(mDocsList.exists());
+        assertSearchTextField(true, query);
+
+        mDevice.pressEnter();
+
+        assertTrue(mDocsList.exists());
+        assertEquals(2, mDocsList.getChildCount());
+        mBot.assertHasDocuments("file1.png", "file10.log");
+        assertSearchTextField(false, query);
+    }
+
+    public void testSearchFoundClearsOnBack() throws Exception {
+        initTestFiles();
+
+        mBot.openRoot(ROOT_0_ID);
+
+        assertDefaultTestDir0();
+
+        String query = "file1";
+        mSearchView.click();
+        mSearchTextField.setText(query);
+
+        mDevice.pressEnter();
+        mDevice.pressBack();
+
+        assertDefaultTestDir0();
+    }
+
+    public void testSearchNoResults() throws Exception {
+        initTestFiles();
+
+        mBot.openRoot(ROOT_0_ID);
+
+        assertDefaultTestDir0();
+
+        String query = "chocolate";
+        mSearchView.click();
+        mSearchTextField.setText(query);
+
+        mDevice.pressEnter();
+
+        assertFalse(mDocsList.exists());
+        assertTrue(mMessageTextView.exists());
+        assertEquals(mContext.getString(R.string.empty), mMessageTextView.getText());
+        assertSearchTextField(false, query);
+    }
+
+    public void testSearchNoResultsClearsOnBack() throws Exception {
+        initTestFiles();
+
+        mBot.openRoot(ROOT_0_ID);
+
+        assertDefaultTestDir0();
+
+        String query = "chocolate";
+        mSearchView.click();
+        mSearchTextField.setText(query);
+
+        mDevice.pressEnter();
+        mDevice.pressBack();
+
+        assertDefaultTestDir0();
+    }
+
+    public void testSearchFoundClearsDirectoryChange() throws Exception {
+        initTestFiles();
+
+        mBot.openRoot(ROOT_0_ID);
+
+        assertDefaultTestDir0();
+
+        String query = "file1";
+        mSearchView.click();
+        mSearchTextField.setText(query);
+
+        mDevice.pressEnter();
+
+        mBot.openRoot(ROOT_1_ID);
+
+         assertDefaultTestDir1();
+
+         mBot.openRoot(ROOT_0_ID);
+
+         assertDefaultTestDir0();
+    }
+
+    private void assertDefaultTestDir0() throws UiObjectNotFoundException {
+        assertTrue(mSearchIcon.exists());
+        assertTrue(mDocsList.exists());
+        assertFalse(mSearchTextField.exists());
+        assertEquals(3, mDocsList.getChildCount());
+        mBot.assertHasDocuments("file2.csv", "file1.png", "file10.log");
+    }
+
+    private void assertDefaultTestDir1() throws UiObjectNotFoundException {
+        assertTrue(mSearchIcon.exists());
+        assertFalse(mSearchTextField.exists());
+        assertTrue(mDocsList.exists());
+        assertEquals(2, mDocsList.getChildCount());
+        mBot.assertHasDocuments("anotherFile0.log", "poodles.text");
+    }
+
+    private void assertSearchTextField(boolean isFocused, String query)
+            throws UiObjectNotFoundException {
+        assertFalse(mSearchIcon.exists());
+        assertTrue(mSearchTextField.exists());
+        assertEquals(isFocused, mSearchTextField.isFocused());
+        assertEquals(query, mSearchTextField.getText());
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
index 50f4628..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);
@@ -135,7 +144,8 @@
             final RootInfo info = entry.getValue();
             final RowBuilder row = result.newRow();
             row.add(Root.COLUMN_ROOT_ID, id);
-            row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD);
+            row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD
+                    | Root.FLAG_SUPPORTS_SEARCH);
             row.add(Root.COLUMN_TITLE, id);
             row.add(Root.COLUMN_DOCUMENT_ID, info.document.documentId);
             row.add(Root.COLUMN_AVAILABLE_BYTES, info.getRemainingCapacity());
@@ -270,8 +280,32 @@
     }
 
     @Override
+    public Cursor querySearchDocuments(String rootId, String query, String[] projection)
+            throws FileNotFoundException {
+
+        StubDocument parentDocument = mRoots.get(rootId).document;
+        if (parentDocument == null || parentDocument.file.isFile()) {
+            throw new FileNotFoundException();
+        }
+
+        final MatrixCursor result = new MatrixCursor(
+                projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
+
+        for (File file : parentDocument.file.listFiles()) {
+            if (file.getName().toLowerCase().contains(query)) {
+                StubDocument document = mStorage.get(getDocumentIdForFile(file));
+                if (document != null) {
+                    includeDocument(result, document);
+                }
+            }
+        }
+        return result;
+    }
+
+    @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();
@@ -281,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);
@@ -302,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
@@ -313,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();
         }
@@ -325,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 {
@@ -430,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);
@@ -506,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) {
@@ -535,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/UiBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/UiBot.java
index 68cdf12..c4def8f 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/UiBot.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/UiBot.java
@@ -187,4 +187,41 @@
         mDevice.wait(Until.findObject(selector), mTimeout);
         return mDevice.findObject(selector);
     }
+
+    private UiObject findObject(String resourceId) {
+        final UiSelector object = new UiSelector().resourceId(resourceId);
+        return mDevice.findObject(object);
+    }
+
+    private UiObject findObject(String parentResourceId, String childResourceId) {
+        final UiSelector selector = new UiSelector()
+                .resourceId(parentResourceId)
+                .childSelector(new UiSelector().resourceId(childResourceId));
+        return mDevice.findObject(selector);
+    }
+
+    UiObject findDocumentsList() {
+        return findObject(
+                "com.android.documentsui:id/container_directory",
+                "com.android.documentsui:id/list");
+    }
+
+    UiObject findSearchView() {
+        return findObject("com.android.documentsui:id/menu_search");
+    }
+
+    UiObject findSearchViewTextField() {
+        return findObject("com.android.documentsui:id/menu_search", "android:id/search_src_text");
+    }
+
+    UiObject findSearchViewIcon() {
+        return findObject("com.android.documentsui:id/menu_search", "android:id/search_button");
+    }
+
+    UiObject findMessageTextView() {
+        return findObject(
+                "com.android.documentsui:id/container_directory",
+                "com.android.documentsui:id/message");
+    }
+
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/BaseCopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/BaseCopyJobTest.java
new file mode 100644
index 0000000..f57ce53
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/BaseCopyJobTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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.android.documentsui.StubProvider.ROOT_0_ID;
+import static com.android.documentsui.StubProvider.ROOT_1_ID;
+import static com.google.common.collect.Lists.newArrayList;
+
+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.RootInfo;
+
+import java.util.List;
+
+@MediumTest
+public abstract class BaseCopyJobTest 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);
+    }
+
+    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 descDir = mDocs.createFolder(testDir, "theDescendent");
+
+        createJob(newArrayList(testDir), descDir).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);
+    }
+
+    final CopyJob createJob(List<Uri> srcs) throws Exception {
+        Uri destination = DocumentsContract.buildDocumentUri(AUTHORITY, mDestRoot.documentId);
+        return createJob(srcs, destination);
+    }
+
+    abstract CopyJob createJob(List<Uri> srcs, Uri 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..c0ce993
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.net.Uri;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+@MediumTest
+public class CopyJobTest extends BaseCopyJobTest {
+
+    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<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 new CopyJob(
+                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcDocs);
+    }
+}
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..d55b6f0 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,171 @@
 
 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)));
-
-        // Just 1 operation: Directory creation.
-        mResolver.waitForChanges(1);
-
-        assertDestFileCount(1);
-
-        // Verify that the dst exists and is a directory.
-        File dst = mStorage.getFile(DST_ROOT, srcPath);
-        assertTrue(dst.isDirectory());
+        mExecutor.isAlive();
+        mExecutor.runAll();
+        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);
-
-        mListener.waitForFinished();
-        mListener.assertFailedCount(1);
-        mListener.assertFileFailed("someDir");
-
-        assertDestFileCount(0);
+        mExecutor.runAll();
+        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");
-
-        assertDestFileCount(0);
+        mExecutor.runAll();
+        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..5e41524
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.net.Uri;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+@MediumTest
+public class MoveJobTest extends BaseCopyJobTest {
+
+    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
+    CopyJob 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 new MoveJob(
+                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcDocs);
+    }
+}
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..72da9a1
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java
@@ -0,0 +1,77 @@
+/*
+ * 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);
+    }
+
+    @Override
+    void cleanup() {}
+
+    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..5c39b78
--- /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 isAlive() {
+        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-af/strings.xml b/packages/Keyguard/res/values-af/strings.xml
index 428c842..1db5f61 100644
--- a/packages/Keyguard/res/values-af/strings.xml
+++ b/packages/Keyguard/res/values-af/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Geen diens nie."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knoppie vir wissel van invoermetode."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Vliegtuigmodus"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Patroon word vereis wanneer jy die toestel herbegin."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN word vereis wanneer jy die toestel herbegin."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Wagwoord word vereis wanneer jy die toestel herbegin."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Patroon word vir bykomende sekuriteit vereis."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN word vir bykomende sekuriteit vereis."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Wagwoord word vir bykomende sekuriteit vereis."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Patroon word vereis wanneer jy profiele wissel."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN word vereis wanneer jy profiele wissel."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Wagwoord word vereis wanneer jy profiele wissel."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Patroon word vereis nadat toestel herbegin het"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN word vereis nadat toestel herbegin het"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Wagwoord word vereis nadat toestel herbegin het"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Patroon word vir bykomende sekuriteit vereis"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN word vir bykomende sekuriteit vereis"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Wagwoord word vir bykomende sekuriteit vereis"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Patroon word vereis wanneer jy profiele wissel"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN word vereis wanneer jy profiele wissel"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Wagwoord word vereis wanneer jy profiele wissel"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Toestel is <xliff:g id="NUMBER_1">%d</xliff:g> uur lank nie ontsluit nie. Bevestig patroon.</item>
       <item quantity="one">Toestel is <xliff:g id="NUMBER_0">%d</xliff:g> uur lank nie ontsluit nie. Bevestig patroon.</item>
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index e0520b1..2b19d7a 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/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="489430505491862444">"መሳሪያውን ዳግም በሚያስጀምሩ ጊዜ ስርዓተ ጥለት ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"መሳሪያውን ዳግም በሚያስጀምሩ ጊዜ ፒን ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"መሳሪያውን ዳግም በሚያስጀምሩ ጊዜ የይለፍ ቃል ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ለተጨማሪ ደህንነት ስርዓተ ጥለት ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ለተጨማሪ ደህንነት ፒን ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ለተጨማሪ ደህንነት የይለፍ ቃል ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"መገለጫዎችን በሚቀይሩ ጊዜ ስርዓተ ጥለት ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"መገለጫዎችን በሚቀይሩ ጊዜ ፒን ያስፈልጋል።"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"መገለጫዎችን በሚቀይሩ ጊዜ የይለፍ ቃል ያስፈልጋል።"</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"መገለጫዎችን በሚቀያይሯቸው ጊዜ ሥርዓተ ጥለት ያስፈልጋል"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"መገለጫዎችን በሚቀያይሯቸው ፒን ያስፈልጋል"</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="one">መሳሪያው ለ<xliff:g id="NUMBER_1">%d</xliff:g>ሰዓቶች አልተከፈተም ነበር። ስርዓተ ጥለት ያረጋግጡ።</item>
       <item quantity="other">መሳሪያው ለ<xliff:g id="NUMBER_1">%d</xliff:g>ሰዓቶች አልተከፈተም ነበር። ስርዓተ ጥለት ያረጋግጡ።</item>
diff --git a/packages/Keyguard/res/values-ar/strings.xml b/packages/Keyguard/res/values-ar/strings.xml
index c2db559..efaad1f 100644
--- a/packages/Keyguard/res/values-ar/strings.xml
+++ b/packages/Keyguard/res/values-ar/strings.xml
@@ -118,15 +118,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="489430505491862444">"يجب رسم النقش عند إعادة تشغيل الجهاز."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"يجب إدخال رقم التعريف الشخصي عند إعادة تشغيل الجهاز."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"يجب إدخال كلمة المرور عند إعادة تشغيل الجهاز."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"يلزم إدخال النمط لمزيد من الأمان."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"يلزم إدخال رقم التعريف الشخصي لمزيد من الأمان."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"يلزم إدخال كلمة المرور لمزيد من الأمان."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"يجب رسم النقش عند تبديل الملفات الشخصية."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"يجب إدخال رقم التعريف الشخصي عند تبديل الملفات الشخصية."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"يجب إدخال كلمة المرور عند تبديل الملفات الشخصية."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"يجب رسم النقش عند تبديل الملفات الشخصية."</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"يجب إدخال رقم التعريف الشخصي عند تبديل الملفات الشخصية."</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="zero">لم يتم إلغاء تأمين الجهاز لمدة <xliff:g id="NUMBER_1">%d</xliff:g> من الساعات. تأكيد النقش.</item>
       <item quantity="two">لم يتم إلغاء تأمين الجهاز لمدة ساعتين (<xliff:g id="NUMBER_1">%d</xliff:g>). تأكيد النقش.</item>
diff --git a/packages/Keyguard/res/values-az-rAZ/strings.xml b/packages/Keyguard/res/values-az-rAZ/strings.xml
index 575d035..4450c01 100644
--- a/packages/Keyguard/res/values-az-rAZ/strings.xml
+++ b/packages/Keyguard/res/values-az-rAZ/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Xidmət yoxdur."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Daxiletmə metodu düyməsinə keç"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Təyyarə rejimi"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Cihazı yenidən başladarkən nümunə kod tələb olunur."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Cihazı yenidən başladarkən PIN kod tələb olunur."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Cihazı yenidən başladarkən parol tələb olunur."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Əlavə təhlükəsizlik üçün model tələb olunur."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Əlavə təhlükəsizlik üçün PIN tələb olunur."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Əlavə təhlükəsizlik üçün parol tələb olunur."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profillər arasında keçid edərkən nümunə kod tələb olunur."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profillər arasında keçid edərkən PIN kod tələb olunur."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profillər arasında keçid edərkən parol tələb olunur."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Cihaz yeniden başladıqdan sonra qəlib kod tələb olunur"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Cihaz yeniden başladıqdan sonra PIN tələb olunur"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Cihaz yeniden başladıqdan sonra parol tələb olunur"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Əlavə təhlükəsizlik üçün qəlib tələb olunur"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Əlavə təhlükəsizlik üçün PIN tələb olunur"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Əlavə təhlükəsizlik üçün parol tələb olunur"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Profillər arasında keçid edərkən qəlib kod tələb olunur"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Profillər arasında keçid edərkən PIN kod tələb olunur"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Profillər arasında keçid edərkən parol tələb olunur"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Cihaz <xliff:g id="NUMBER_1">%d</xliff:g> saat kiliddən çıxarılmayıb. Nümunə kodu təsdiq edin.</item>
       <item quantity="one">Cihaz <xliff:g id="NUMBER_0">%d</xliff:g> saat kiliddən çıxarılmayıb. Nümunə kodu təsdiq edin.</item>
diff --git a/packages/Keyguard/res/values-b+sr+Latn/strings.xml b/packages/Keyguard/res/values-b+sr+Latn/strings.xml
index 8b6ba5d..0eb4210 100644
--- a/packages/Keyguard/res/values-b+sr+Latn/strings.xml
+++ b/packages/Keyguard/res/values-b+sr+Latn/strings.xml
@@ -112,15 +112,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Oflajn ste."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Dugme Promeni metod unosa."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Režim rada u avionu"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Šablon je obavezan kada ponovo pokrećete uređaj."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN je obavezan kada ponovo pokrećete uređaj."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Lozinka je obavezna kada ponovo pokrećete uređaj."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Potreban je šablon radi dodatne bezbednosti."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Potreban je PIN radi dodatne bezbednosti."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Potrebna je lozinka radi dodatne bezbednosti."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Šablon je obavezan kada prelazite sa jednog profila na drugi."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN je obavezan kada prelazite sa jednog profila na drugi."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Lozinka je obavezna kada prelazite sa jednog profila na drugi."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Treba da unesete šablon kada se uređaj ponovo pokrene"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Treba da unesete PIN kada se uređaj ponovo pokrene"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Treba da uneste lozinku kada se uređaj ponovo pokrene"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Treba da unesete šablon radi dodatne bezbednosti"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Treba da unesete PIN radi dodatne bezbednosti"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Treba da unesete lozinku radi dodatne bezbednosti"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Treba da unesete šablon kada prelazite sa jednog profila na drugi"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Treba da unesete PIN kada prelazite sa jednog profila na drugi"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Treba da unesete lozinku kada prelazite sa jednog profila na drugi"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Niste otključali uređaj <xliff:g id="NUMBER_1">%d</xliff:g> sat. Potvrdite šablon.</item>
       <item quantity="few">Niste otključali uređaj <xliff:g id="NUMBER_1">%d</xliff:g> sata. Potvrdite šablon.</item>
diff --git a/packages/Keyguard/res/values-bg/strings.xml b/packages/Keyguard/res/values-bg/strings.xml
index 2c42dc0..ae95c49 100644
--- a/packages/Keyguard/res/values-bg/strings.xml
+++ b/packages/Keyguard/res/values-bg/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="489430505491862444">"При рестартиране на устройството ви се изисква фигура."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"При рестартиране на устройството ви се изисква ПИН код."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"При рестартиране на устройството ви се изисква парола."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"За допълнителна сигурност се изисква фигура."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"За допълнителна сигурност се изисква ПИН."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"За допълнителна сигурност се изисква парола."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"При превключване между потребителските профили се изисква фигура."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"При превключване между потребителските профили се изисква ПИН код."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"При превключване между потребителските профили се изисква парола."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"При превключване между потребителските профили се изисква фигура"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"При превключване между потребителските профили се изисква ПИН код"</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>
diff --git a/packages/Keyguard/res/values-bn-rBD/strings.xml b/packages/Keyguard/res/values-bn-rBD/strings.xml
index bec579c..1dd8af8 100644
--- a/packages/Keyguard/res/values-bn-rBD/strings.xml
+++ b/packages/Keyguard/res/values-bn-rBD/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="489430505491862444">"যখন আপনি ডিভাইস পুনর্সূচনা করবেন তখন প্যাটার্নের প্রয়োজন হবে৷"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"যখন আপনি ডিভাইস পুনর্সূচনা করবেন তখন পিন এর প্রয়োজন হবে৷"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"যখন আপনি ডিভাইস পুনর্সূচনা করবেন তখন পাসওয়ার্ডের প্রয়োজন হবে৷"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"অতিরিক্ত সুরক্ষার জন্য প্যাটার্ন প্রয়োজন৷"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"অতিরিক্ত সুরক্ষার জন্য PIN প্রয়োজন৷"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"অতিরিক্ত সুরক্ষার জন্য পাসওয়ার্ড প্রয়োজন৷"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"যখন আপনি প্রোফাইলগুলি পাল্টাবেন তখন প্যাটার্নের প্রয়োজন হবে৷"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"যখন আপনি প্রোফাইলগুলি পাল্টাবেন তখন পিন এর প্রয়োজন হবে৷"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"যখন আপনি প্রোফাইলগুলি পাল্টাবেন তখন পাসওয়ার্ডের প্রয়োজন হবে৷"</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="one">ডিভাইস <xliff:g id="NUMBER_1">%d</xliff:g> ঘন্টার জন্য আনলক করা হয়নি। প্যাটার্ন নিশ্চিত করুন।</item>
       <item quantity="other">ডিভাইস <xliff:g id="NUMBER_1">%d</xliff:g> ঘন্টার জন্য আনলক করা হয়নি। প্যাটার্ন নিশ্চিত করুন।</item>
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
index 30d9289..70e9fd1 100644
--- a/packages/Keyguard/res/values-ca/strings.xml
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sense servei."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botó de canvi del mètode d\'entrada."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Mode d\'avió"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Cal introduir el patró en reiniciar el dispositiu."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Cal introduir el PIN en reiniciar el dispositiu."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Cal introduir la contrasenya en reiniciar el dispositiu."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"El patró és necessari per disposar de més seguretat."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"El PIN és necessari per disposar de més seguretat."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"La contrasenya és necessària per disposar de més seguretat."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Cal introduir el patró en canviar de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Cal introduir el PIN en canviar de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Cal introduir la contrasenya en canviar de perfil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Cal introduir el patró quan es reinicia el dispositiu"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Cal introduir el PIN quan es reinicia el dispositiu"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Cal introduir la contrasenya quan es reinicia el dispositiu"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Cal introduir el patró per disposar de més seguretat"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Cal introduir el PIN per disposar de més seguretat"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Cal introduir la contrasenya per disposar de més seguretat"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Cal introduir el patró en canviar de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Cal introduir el PIN en canviar de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Cal introduir la contrasenya en canviar de perfil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Fa <xliff:g id="NUMBER_1">%d</xliff:g> hores que no es desbloqueja el dispositiu. Confirma el patró.</item>
       <item quantity="one">Fa <xliff:g id="NUMBER_0">%d</xliff:g> hora que no es desbloqueja el dispositiu. Confirma el patró.</item>
diff --git a/packages/Keyguard/res/values-cs/strings.xml b/packages/Keyguard/res/values-cs/strings.xml
index 44c7f27..96944cf 100644
--- a/packages/Keyguard/res/values-cs/strings.xml
+++ b/packages/Keyguard/res/values-cs/strings.xml
@@ -114,15 +114,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Žádný signál."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačítko přepnutí metody zadávání"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Režim Letadlo"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Po restartu zařízení je vyžadováno gesto."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Po restartu zařízení je vyžadován PIN."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Po restartu zařízení je vyžadováno heslo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Za účelem zvýšení zabezpečení je vyžadováno gesto."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Za účelem zvýšení zabezpečení je vyžadován kód PIN."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Za účelem zvýšení zabezpečení je vyžadováno heslo."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po přepnutí profilů je vyžadováno gesto."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po přepnutí profilů je vyžadován PIN."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po přepnutí profilů je vyžadováno heslo."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Po restartování zařízení je vyžadováno gesto"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Po restartování zařízení je vyžadován kód PIN"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Po restartování zařízení je vyžadováno heslo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Za účelem zvýšení zabezpečení je vyžadováno gesto"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Za účelem zvýšení zabezpečení je vyžadován kód PIN"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Za účelem zvýšení zabezpečení je vyžadováno heslo"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Po přepnutí profilů je vyžadováno gesto"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Po přepnutí profilů je vyžadován kód PIN"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Po přepnutí profilů je vyžadováno heslo"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="few">Zařízení již <xliff:g id="NUMBER_1">%d</xliff:g> hodiny nebylo odemknuto. Potvrďte gesto.</item>
       <item quantity="many">Zařízení již <xliff:g id="NUMBER_1">%d</xliff:g> hodiny nebylo odemknuto. Potvrďte gesto.</item>
diff --git a/packages/Keyguard/res/values-da/strings.xml b/packages/Keyguard/res/values-da/strings.xml
index b81305b..5ce1ef0 100644
--- a/packages/Keyguard/res/values-da/strings.xml
+++ b/packages/Keyguard/res/values-da/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ingen dækning."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Skift indtastningsmetode-knappen."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Flytilstand"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Du skal indtaste et mønster, når du genstarter enheden."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Du skal indtaste en pinkode, når du genstarter enheden."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Du skal indtaste en adgangskode, når du genstarter enheden."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Der kræves et mønster som ekstra beskyttelse."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Der kræves en pinkode som ekstra beskyttelse."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Der kræves en adgangskode som ekstra beskyttelse."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Du skal indtaste et mønster, når du skifter profiler."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Du skal indtaste en pinkode, når du skifter profiler."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Du skal indtaste en adgangskode, når du skifter profiler."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Du skal indtaste et mønster efter genstart af enheden"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Der skal indtaste en pinkode efter genstart af enheden"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Du skal indtaste en adgangskode efter genstart af enheden"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Der kræves et mønster som ekstra beskyttelse"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Der kræves en pinkode som ekstra beskyttelse"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Der kræves en adgangskode som ekstra beskyttelse"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Du skal indtaste et mønster, når du skifter profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Du skal indtaste en pinkode, når du skifter profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Du skal indtaste en adgangskode, når du skifter profil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Enheden blev sidst låst op for <xliff:g id="NUMBER_1">%d</xliff:g> timer siden. Bekræft mønsteret.</item>
       <item quantity="other">Enheden blev sidst låst op for <xliff:g id="NUMBER_1">%d</xliff:g> timer siden. Bekræft mønsteret.</item>
diff --git a/packages/Keyguard/res/values-de/strings.xml b/packages/Keyguard/res/values-de/strings.xml
index 40ddfc2..f1fc198 100644
--- a/packages/Keyguard/res/values-de/strings.xml
+++ b/packages/Keyguard/res/values-de/strings.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="719438068451601849">"Keyguard"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN-Code eingeben"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"Geben Sie den PUK-Code der SIM-Karte und den neuen PIN-Code ein."</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"Gib den PUK-Code der SIM-Karte und den neuen PIN-Code ein."</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK-Code der SIM-Karte"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Neuer PIN-Code der SIM-Karte"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Zur Passworteingabe berühren"</font></string>
@@ -39,10 +39,10 @@
     <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Keine SIM-Karte"</string>
     <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Keine SIM-Karte im Tablet"</string>
     <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Keine SIM-Karte im Telefon"</string>
-    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Legen Sie eine SIM-Karte ein."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-Karte fehlt oder ist nicht lesbar. Bitte legen Sie eine SIM-Karte ein."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Lege eine SIM-Karte ein."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-Karte fehlt oder ist nicht lesbar. Bitte lege eine SIM-Karte ein."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM-Karte unbrauchbar"</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Ihre SIM-Karte wurde dauerhaft deaktiviert.\n Wenden Sie sich an Ihren Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Deine SIM-Karte wurde dauerhaft deaktiviert.\n Wende dich an deinen Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
     <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-Karte ist gesperrt."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-Karte ist gesperrt. PUK-Eingabe erforderlich."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM-Karte wird entsperrt…"</string>
@@ -61,48 +61,48 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Falsches Muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Falsches Passwort"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Falsche PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuchen Sie es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuche es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Muster zeichnen"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM-PIN eingeben"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"SIM-PIN für \"<xliff:g id="CARRIER">%1$s</xliff:g>\" eingeben"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN eingeben"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"Passwort eingeben"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Die SIM-Karte ist jetzt deaktiviert. Geben Sie den PUK-Code ein, um fortzufahren. Weitere Informationen erhalten Sie von Ihrem Mobilfunkanbieter."</string>
-    <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"Die SIM-Karte \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ist jetzt deaktiviert. Geben Sie den PUK-Code ein, um fortzufahren. Weitere Informationen erhalten Sie von Ihrem Mobilfunkanbieter."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Weitere Informationen erhältst du von deinem Mobilfunkanbieter."</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"Die SIM-Karte \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Weitere Informationen erhältst du von deinem Mobilfunkanbieter."</string>
     <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewünschten PIN-Code eingeben"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewünschten PIN-Code bestätigen"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-Karte wird entsperrt…"</string>
-    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Geben Sie eine 4- bis 8-stellige PIN ein."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Gib eine 4- bis 8-stellige PIN ein."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Der PUK-Code muss mindestens 8 Ziffern betragen."</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"Geben Sie den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Gib den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-Codes stimmen nicht überein"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zu viele Musterversuche"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Sie haben Ihre PIN <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Tablet zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Telefon zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Dieses Tablet wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Dieses Telefon wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Dieser Nutzer wird nun entfernt und alle Nutzerdaten werden gelöscht."</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Dieser Nutzer wird nun entfernt und alle Nutzerdaten werden gelöscht."</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Arbeitsprofil entfernt. Dadurch werden alle Profildaten gelöscht."</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Sie haben <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Arbeitsprofil entfernt. Dadurch werden alle Profildaten gelöscht."</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Falscher PIN-Code der SIM-Karte. Bitte wenden Sie sich an Ihren Mobilfunkanbieter, damit er Ihr Gerät entsperrt."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du hast deine PIN <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du hast dein Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nVersuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nVersuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Tablet zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieses Telefon zurückgesetzt. Dadurch werden alle Gerätedaten gelöscht."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Dieses Tablet wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="7154028908459817066">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Dieses Telefon wird nun zurückgesetzt und alle Gerätedaten werden gelöscht."</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="6159955099372112688">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="6945823186629369880">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird dieser Nutzer entfernt. Dadurch werden alle Nutzerdaten gelöscht."</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="3963486905355778734">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Dieser Nutzer wird nun entfernt und alle Nutzerdaten werden gelöscht."</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="7729009752252111673">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Dieser Nutzer wird nun entfernt und alle Nutzerdaten werden gelöscht."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="4621778507387853694">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Arbeitsprofil entfernt. Dadurch werden alle Profildaten gelöscht."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"Du hast <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wird das Arbeitsprofil entfernt. Dadurch werden alle Profildaten gelöscht."</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Falscher PIN-Code der SIM-Karte. Bitte wende dich an deinen Mobilfunkanbieter, damit er dein Gerät entsperrt."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
-      <item quantity="other">Falscher PIN-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche.</item>
-      <item quantity="one">Falscher PIN-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor Sie das Gerät von Ihrem Mobilfunkanbieter entsperren lassen müssen.</item>
+      <item quantity="other">Falscher PIN-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche.</item>
+      <item quantity="one">Falscher PIN-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor du das Gerät von deinem Mobilfunkanbieter entsperren lassen musst.</item>
     </plurals>
-    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Die SIM-Karte kann nicht verwendet werden. Bitte wenden Sie sich an Ihren Mobilfunkanbieter."</string>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Die SIM-Karte kann nicht verwendet werden. Bitte wende dich an deinen Mobilfunkanbieter."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="7576227366999858780">
-      <item quantity="other">Falscher PUK-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche, bevor Ihre SIM-Karte endgültig gesperrt wird.</item>
-      <item quantity="one">Falscher PUK-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor Ihre SIM-Karte endgültig gesperrt wird.</item>
+      <item quantity="other">Falscher PUK-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche, bevor deine SIM-Karte endgültig gesperrt wird.</item>
+      <item quantity="one">Falscher PUK-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor deine SIM-Karte endgültig gesperrt wird.</item>
     </plurals>
     <string name="kg_password_pin_failed" msgid="6268288093558031564">"Fehler beim Entsperren mit der PIN der SIM-Karte"</string>
     <string name="kg_password_puk_failed" msgid="2838824369502455984">"Fehler beim Entsperren mithilfe des PUK-Codes der SIM-Karte"</string>
@@ -110,26 +110,26 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Kein Dienst"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Schaltfläche zum Ändern der Eingabemethode"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Flugmodus"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Beim Neustart des Geräts ist die Eingabe des Musters erforderlich."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Beim Neustart des Geräts ist die Eingabe der PIN erforderlich."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Beim Neustart des Geräts ist die Eingabe des Passworts erforderlich."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Zur Verbesserung der Sicherheit ist ein Muster erforderlich."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Zur Verbesserung der Sicherheit ist eine PIN erforderlich."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Zur Verbesserung der Sicherheit ist ein Passwort erforderlich."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Beim Profilwechsel ist die Eingabe des Musters erforderlich."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Beim Profilwechsel ist die Eingabe der PIN erforderlich."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Beim Profilwechsel ist die Eingabe des Passworts erforderlich."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Nach dem Neustart des Geräts ist die Eingabe des Musters erforderlich."</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Nach dem Neustart des Geräts ist die Eingabe der PIN erforderlich."</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Nach dem Neustart des Geräts ist die Eingabe des Passworts erforderlich."</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Zur Verbesserung der Sicherheit ist ein Muster erforderlich."</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Zur Verbesserung der Sicherheit ist eine PIN erforderlich."</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Zur Verbesserung der Sicherheit ist ein Passwort erforderlich."</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Beim Profilwechsel ist die Eingabe des Musters erforderlich."</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Beim Profilwechsel ist die Eingabe der PIN erforderlich."</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Beim Profilwechsel ist die Eingabe des Passworts erforderlich."</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
-      <item quantity="other">Das Gerät wurde seit <xliff:g id="NUMBER_1">%d</xliff:g> Stunden nicht mehr entsperrt. Bestätigen Sie das Muster.</item>
-      <item quantity="one">Das Gerät wurde seit <xliff:g id="NUMBER_0">%d</xliff:g> Stunde nicht mehr entsperrt. Bestätigen Sie das Muster.</item>
+      <item quantity="other">Das Gerät wurde seit <xliff:g id="NUMBER_1">%d</xliff:g> Stunden nicht mehr entsperrt. Bestätige das Muster.</item>
+      <item quantity="one">Das Gerät wurde seit <xliff:g id="NUMBER_0">%d</xliff:g> Stunde nicht mehr entsperrt. Bestätige das Muster.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="2118758475374354849">
-      <item quantity="other">Das Gerät wurde seit <xliff:g id="NUMBER_1">%d</xliff:g> Stunden nicht mehr entsperrt. Bestätigen Sie die PIN.</item>
-      <item quantity="one">Das Gerät wurde seit <xliff:g id="NUMBER_0">%d</xliff:g> Stunde nicht mehr entsperrt. Bestätigen Sie die PIN.</item>
+      <item quantity="other">Das Gerät wurde seit <xliff:g id="NUMBER_1">%d</xliff:g> Stunden nicht mehr entsperrt. Bestätige die PIN.</item>
+      <item quantity="one">Das Gerät wurde seit <xliff:g id="NUMBER_0">%d</xliff:g> Stunde nicht mehr entsperrt. Bestätige die PIN.</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="5132693663364913675">
-      <item quantity="other">Das Gerät wurde seit <xliff:g id="NUMBER_1">%d</xliff:g> Stunden nicht mehr entsperrt. Bestätigen Sie das Passwort.</item>
-      <item quantity="one">Das Gerät wurde seit <xliff:g id="NUMBER_0">%d</xliff:g> Stunde nicht mehr entsperrt. Bestätigen Sie das Passwort.</item>
+      <item quantity="other">Das Gerät wurde seit <xliff:g id="NUMBER_1">%d</xliff:g> Stunden nicht mehr entsperrt. Bestätige das Passwort.</item>
+      <item quantity="one">Das Gerät wurde seit <xliff:g id="NUMBER_0">%d</xliff:g> Stunde nicht mehr entsperrt. Bestätige das Passwort.</item>
     </plurals>
     <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Nicht erkannt"</string>
 </resources>
diff --git a/packages/Keyguard/res/values-el/strings.xml b/packages/Keyguard/res/values-el/strings.xml
index dc6cc05..535bee8 100644
--- a/packages/Keyguard/res/values-el/strings.xml
+++ b/packages/Keyguard/res/values-el/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="489430505491862444">"Απαιτείται μοτίβο κατά την επανεκκίνηση της συσκευής."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Απαιτείται PIN κατά την επανεκκίνηση της συσκευής."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Απαιτείται κωδικός πρόσβασης κατά την επανεκκίνηση της συσκευής."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Απαιτείται μοτίβο για πρόσθετη ασφάλεια."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Απαιτείται PIN για πρόσθετη ασφάλεια."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Απαιτείται κωδικός πρόσβασης για πρόσθετη ασφάλεια."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Απαιτείται μοτίβο κατά την εναλλαγή προφίλ."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Απαιτείται PIN κατά την εναλλαγή προφίλ."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Απαιτείται κωδικός πρόσβασης κατά την εναλλαγή προφίλ."</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> ώρες. Επιβεβαιώστε το μοτίβο.</item>
       <item quantity="one">Η συσκευή δεν έχει ξεκλειδωθεί για <xliff:g id="NUMBER_0">%d</xliff:g> ώρα. Επιβεβαιώστε το μοτίβο.</item>
diff --git a/packages/Keyguard/res/values-en-rAU/strings.xml b/packages/Keyguard/res/values-en-rAU/strings.xml
index 5aec0e9..63b2137 100644
--- a/packages/Keyguard/res/values-en-rAU/strings.xml
+++ b/packages/Keyguard/res/values-en-rAU/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Aeroplane mode"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pattern required when you restart device."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN required when you restart device."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password required when you restart device."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern required for additional security."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN required for additional security."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password required for additional security."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pattern required when you switch profiles."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN required when you switch profiles."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password required when you switch profiles."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Pattern required after device restarts"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN required after device restarts"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Password required after device restarts"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Pattern required for additional security"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN required for additional security"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Password required for additional security"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Pattern required when you switch profiles"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN required when you switch profiles"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Password required when you switch profiles"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm pattern.</item>
       <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_0">%d</xliff:g> hour. Confirm pattern.</item>
diff --git a/packages/Keyguard/res/values-en-rGB/strings.xml b/packages/Keyguard/res/values-en-rGB/strings.xml
index 5aec0e9..63b2137 100644
--- a/packages/Keyguard/res/values-en-rGB/strings.xml
+++ b/packages/Keyguard/res/values-en-rGB/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Aeroplane mode"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pattern required when you restart device."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN required when you restart device."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password required when you restart device."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern required for additional security."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN required for additional security."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password required for additional security."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pattern required when you switch profiles."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN required when you switch profiles."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password required when you switch profiles."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Pattern required after device restarts"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN required after device restarts"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Password required after device restarts"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Pattern required for additional security"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN required for additional security"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Password required for additional security"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Pattern required when you switch profiles"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN required when you switch profiles"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Password required when you switch profiles"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm pattern.</item>
       <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_0">%d</xliff:g> hour. Confirm pattern.</item>
diff --git a/packages/Keyguard/res/values-en-rIN/strings.xml b/packages/Keyguard/res/values-en-rIN/strings.xml
index 5aec0e9..63b2137 100644
--- a/packages/Keyguard/res/values-en-rIN/strings.xml
+++ b/packages/Keyguard/res/values-en-rIN/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Aeroplane mode"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pattern required when you restart device."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN required when you restart device."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password required when you restart device."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern required for additional security."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN required for additional security."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password required for additional security."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pattern required when you switch profiles."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN required when you switch profiles."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password required when you switch profiles."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Pattern required after device restarts"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN required after device restarts"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Password required after device restarts"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Pattern required for additional security"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN required for additional security"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Password required for additional security"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Pattern required when you switch profiles"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN required when you switch profiles"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Password required when you switch profiles"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="NUMBER_1">%d</xliff:g> hours. Confirm pattern.</item>
       <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="NUMBER_0">%d</xliff:g> hour. Confirm pattern.</item>
diff --git a/packages/Keyguard/res/values-es-rUS/strings.xml b/packages/Keyguard/res/values-es-rUS/strings.xml
index bbfda15..cf903eb 100644
--- a/packages/Keyguard/res/values-es-rUS/strings.xml
+++ b/packages/Keyguard/res/values-es-rUS/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sin servicio"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de entrada"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modo de avión"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Se solicita el patrón al reiniciar el dispositivo."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Se solicita el PIN al reiniciar el dispositivo."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Se solicita la contraseña al reiniciar el dispositivo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Por razones de seguridad, debe resolverse el patrón."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Por razones de seguridad, escribe el PIN."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Por razones de seguridad, ingresa la contraseña."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Se solicita el patrón al cambiar de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Se solicita el PIN al cambiar de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Se solicita la contraseña al cambiar de perfil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Se requiere el patrón después de reiniciar el dispositivo"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Se requiere el PIN después de reiniciar el dispositivo"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Se requiere la contraseña después de reiniciar el dispositivo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Se requiere el patrón por razones de seguridad"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Se requiere el PIN por razones de seguridad"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Se requiere la contraseña por razones de seguridad"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Se requiere el patrón al cambiar de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Se requiere el PIN al cambiar de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Se requiere la contraseña al cambiar de perfil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Hace <xliff:g id="NUMBER_1">%d</xliff:g> horas que no se desbloquea el dispositivo. Confirma el patrón.</item>
       <item quantity="one">Hace <xliff:g id="NUMBER_0">%d</xliff:g> hora que no se desbloquea el dispositivo. Confirma el patrón.</item>
diff --git a/packages/Keyguard/res/values-es/strings.xml b/packages/Keyguard/res/values-es/strings.xml
index d329c2ab..a131cc1 100644
--- a/packages/Keyguard/res/values-es/strings.xml
+++ b/packages/Keyguard/res/values-es/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sin servicio"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de entrada"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modo avión"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Se debe introducir el patrón cuando se reinicia el dispositivo."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Se debe introducir el PIN cuando se reinicia el dispositivo."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Se debe introducir la contraseña cuando se reinicia el dispositivo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Es necesario introducir el patrón como medida de seguridad adicional."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Es necesario introducir el PIN como medida de seguridad adicional."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Es necesario introducir la contraseña como medida de seguridad adicional."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Se debe introducir el patrón cuando se cambia de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Se debe introducir el PIN cuando se cambia de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Se debe introducir la contraseña cuando se cambia de perfil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Debes introducir el patrón después de reiniciar el dispositivo"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Debes introducir el PIN después de reiniciar el dispositivo"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Debes introducir la contraseña después de reiniciar el dispositivo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Debes introducir el patrón como medida de seguridad adicional"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Debes introducir el PIN como medida de seguridad adicional"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Debes introducir la contraseña como medida de seguridad adicional"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Debes introducir el patrón cuando cambies de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Debes introducir el PIN cuando cambies de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Debes introducir la contraseña cuando cambies de perfil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">El dispositivo no se ha desbloqueado durante <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirma el patrón.</item>
       <item quantity="one">El dispositivo no se ha desbloqueado durante <xliff:g id="NUMBER_0">%d</xliff:g> hora. Confirma el patrón.</item>
diff --git a/packages/Keyguard/res/values-et-rEE/strings.xml b/packages/Keyguard/res/values-et-rEE/strings.xml
index e3ad33a..47aadf0 100644
--- a/packages/Keyguard/res/values-et-rEE/strings.xml
+++ b/packages/Keyguard/res/values-et-rEE/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Teenus puudub."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Sisestusmeetodi vahetamise nupp."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Lennukirežiim"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Seadme taaskäivitamisel on vaja mustrit."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Seadme taaskäivitamisel on vaja PIN-koodi."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Seadme taaskäivitamisel on vaja parooli."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Täiendava turvalisuse huvides on vaja sisestada muster."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Täiendava turvalisuse huvides on vaja sisestada PIN-kood."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Täiendava turvalisuse huvides on vaja sisestada parool."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profiilide vahetamisel on vaja mustrit."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profiilide vahetamisel on vaja PIN-koodi."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profiilide vahetamisel on vaja parooli."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Pärast seadme taaskäivitamist tuleb sisestada muster"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Pärast seadme taaskäivitamist tuleb sisestada PIN-kood"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Pärast seadme taaskäivitamist tuleb sisestada parool"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Lisaturvalisuse huvides tuleb sisestada muster"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Lisaturvalisuse huvides tuleb sisestada PIN-kood"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Lisaturvalisuse huvides tuleb sisestada parool"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Profiilide vahetamisel tuleb sisestada muster"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Profiilide vahetamisel tuleb sisestada PIN-kood"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Profiilide vahetamisel tuleb sisestada parool"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Seadet pole avatud <xliff:g id="NUMBER_1">%d</xliff:g> tundi. Kinnitage muster.</item>
       <item quantity="one">Seadet pole avatud <xliff:g id="NUMBER_0">%d</xliff:g> tund. Kinnitage muster.</item>
diff --git a/packages/Keyguard/res/values-eu-rES/strings.xml b/packages/Keyguard/res/values-eu-rES/strings.xml
index 19531bd..1c834e9 100644
--- a/packages/Keyguard/res/values-eu-rES/strings.xml
+++ b/packages/Keyguard/res/values-eu-rES/strings.xml
@@ -110,15 +110,15 @@
     <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="489430505491862444">"Gailua berrabiarazi duzunez, eredua marraztu behar duzu."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Gailua berrabiarazi duzunez, PIN kodea idatzi behar duzu."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Gailua berrabiarazi duzunez, pasahitza idatzi behar duzu."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Segurtasun handiagoa izateko, eredua behar da."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Segurtasun handiagoa izateko, PIN kodea behar da."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Segurtasun handiagoa izateko, pasahitza behar da."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profilez aldatu duzunez, eredua marraztu behar duzu."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profilez aldatu duzunez, PIN kodea idatzi behar duzu."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profilez aldatu duzunez, pasahitza idatzi behar duzu."</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>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Segurtasun handiagoa izateko, PIN kodea behar da"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Segurtasun handiagoa izateko, pasahitza behar da"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Eredua marraztu beharko duzu profilez aldatzen baduzu"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN kodea idatzi beharko duzu profilez aldatzen baduzu"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Pasahitza idatzi beharko duzu profilez aldatzen baduzu"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Gailua ez da desblokeatu <xliff:g id="NUMBER_1">%d</xliff:g> orduz. Berretsi eredua.</item>
       <item quantity="one">Gailua ez da desblokeatu <xliff:g id="NUMBER_0">%d</xliff:g> orduz. Berretsi eredua.</item>
diff --git a/packages/Keyguard/res/values-fa/strings.xml b/packages/Keyguard/res/values-fa/strings.xml
index 75e38a2..166e0d9 100644
--- a/packages/Keyguard/res/values-fa/strings.xml
+++ b/packages/Keyguard/res/values-fa/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="489430505491862444">"هنگامی که دستگاه را راه‌اندازی مجدد می‌کنید الگو درخواست می‌شود."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"هنگامی که دستگاه را راه‌اندازی مجدد می‌کنید پین درخواست می‌شود."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"هنگامی که دستگاه را راه‌اندازی مجدد می‌کنید گذرواژه درخواست می‌شود."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"برای ایمنی بیشتر به الگو نیاز است."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"برای ایمنی بیشتر به پین نیاز است."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"برای ایمنی بیشتر به گذرواژه نیاز است."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"هنگامی که میان نمایه‌ها جابجا می‌شوید، الگو درخواست می‌شود."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"هنگامی که میان نمایه‌ها جابجا می‌شوید، پین درخواست می‌شود."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"هنگامی که میان نمایه‌ها جابجا می‌شوید، گذرواژه درخواست می‌شود."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"بعد از تغییر نمایه‌ها باید الگو وارد شود"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"بعد از تغییر نمایه‌ها باید پین وارد شود"</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="one">قفل دستگاه به مدت <xliff:g id="NUMBER_1">%d</xliff:g> ساعت باز نشده است. الگو را تأیید کنید.</item>
       <item quantity="other">قفل دستگاه به مدت <xliff:g id="NUMBER_1">%d</xliff:g> ساعت باز نشده است. الگو را تأیید کنید.</item>
diff --git a/packages/Keyguard/res/values-fi/strings.xml b/packages/Keyguard/res/values-fi/strings.xml
index e3e6e64..bba241e 100644
--- a/packages/Keyguard/res/values-fi/strings.xml
+++ b/packages/Keyguard/res/values-fi/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ei yhteyttä."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Syöttötavan vaihtopainike."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Lentokonetila"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Kuvio vaaditaan laitteen uudelleenkäynnistyksen yhteydessä."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN-koodi vaaditaan laitteen uudelleenkäynnistyksen yhteydessä."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Salasana vaaditaan laitteen uudelleenkäynnistyksen yhteydessä."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Kuvio parantaa suojaustasi."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-koodi parantaa suojaustasi."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Salasana parantaa suojaustasi."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Kuvio vaaditaan profiilia vaihdettaessa."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN-koodi vaaditaan profiilia vaihdettaessa."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Salasana vaaditaan profiilia vaihdettaessa."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Kuvio vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN-koodi vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Salasana vaaditaan laitteen uudelleenkäynnistyksen jälkeen."</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Kuvio vaaditaan suojauksen parantamiseksi."</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN-koodi vaaditaan suojauksen parantamiseksi."</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Salasana vaaditaan suojauksen parantamiseksi."</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Kuvio vaaditaan profiilia vaihdettaessa."</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN-koodi vaaditaan profiilia vaihdettaessa."</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Salasana vaaditaan profiilia vaihdettaessa."</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Laitteen lukitusta ei ole avattu <xliff:g id="NUMBER_1">%d</xliff:g> tuntiin. Vahvista kuvio.</item>
       <item quantity="one">Laitteen lukitusta ei ole avattu <xliff:g id="NUMBER_0">%d</xliff:g> tuntiin. Vahvista kuvio.</item>
diff --git a/packages/Keyguard/res/values-fr-rCA/strings.xml b/packages/Keyguard/res/values-fr-rCA/strings.xml
index e233af2..6b63e04 100644
--- a/packages/Keyguard/res/values-fr-rCA/strings.xml
+++ b/packages/Keyguard/res/values-fr-rCA/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Aucun service"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bouton \"Changer le mode de saisie\""</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Mode Avion"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Veuillez entrer le motif au redémarrage de l\'appareil."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Veuillez entrer le NIP au redémarrage de l\'appareil."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Veuillez entrer le mot de passe au redémarrage de l\'appareil."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Motif requis pour plus de sécurité."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"NIP requis pour plus de sécurité."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Mot de passe requis pour plus de sécurité."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Veuillez tracer le motif lorsque vous changez de profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Veuillez entrer le NIP lorsque vous changez de profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Veuillez entrer le mot de passe lorsque vous changez de profil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Le motif est exigé après le redémarrage de l\'appareil"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Le NIP est exigé après le redémarrage de l\'appareil"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Le mot de passe est exigé après le redémarrage de l\'appareil"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Le motif est exigé pour plus de sécurité"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Le NIP est exigé pour plus de sécurité"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Le mot de passe est exigé pour plus de sécurité"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Le motif est exigé lorsque vous changez de profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Le NIP est exigé lorsque vous changez de profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Le mot de passe est exigé lorsque vous changez de profil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heure. Confirmez le motif.</item>
       <item quantity="other">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heures. Confirmez le motif.</item>
diff --git a/packages/Keyguard/res/values-fr/strings.xml b/packages/Keyguard/res/values-fr/strings.xml
index b7590bd..73b9552 100644
--- a/packages/Keyguard/res/values-fr/strings.xml
+++ b/packages/Keyguard/res/values-fr/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Aucun service"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bouton \"Changer le mode de saisie\""</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Mode Avion"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Veuillez saisir le schéma au redémarrage de l\'appareil."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Veuillez saisir le code d\'accès au redémarrage de l\'appareil."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Veuillez saisir le mot de passe au redémarrage de l\'appareil."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Veuillez saisir le schéma pour renforcer la sécurité."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Veuillez saisir le code d\'accès pour renforcer la sécurité."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Veuillez saisir le mot de passe pour renforcer la sécurité."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Veuillez saisir le schéma lorsque vous changez de profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Veuillez saisir le code d\'accès lorsque vous changez de profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Veuillez saisir le mot de passe lorsque vous changez de profil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Veuillez saisir le schéma après le redémarrage de l\'appareil."</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Veuillez saisir le code d\'accès après le redémarrage de l\'appareil."</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Veuillez saisir le mot de passe après le redémarrage de l\'appareil."</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Veuillez saisir le schéma pour renforcer la sécurité."</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Veuillez saisir le code d\'accès pour renforcer la sécurité."</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Veuillez saisir le mot de passe pour renforcer la sécurité."</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Veuillez saisir le schéma lorsque vous changez de profil."</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Veuillez saisir le code d\'accès lorsque vous changez de profil."</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Veuillez saisir le mot de passe lorsque vous changez de profil."</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heure. Confirmez le schéma.</item>
       <item quantity="other">L\'appareil n\'a pas été déverrouillé depuis <xliff:g id="NUMBER_1">%d</xliff:g> heures. Confirmez le schéma.</item>
diff --git a/packages/Keyguard/res/values-gl-rES/strings.xml b/packages/Keyguard/res/values-gl-rES/strings.xml
index bd7f1f2..05767c9 100644
--- a/packages/Keyguard/res/values-gl-rES/strings.xml
+++ b/packages/Keyguard/res/values-gl-rES/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Non hai servizo."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Cambiar o botón do método de entrada."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modo avión"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"É necesario o padrón para reiniciar o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"É necesario o PIN para reiniciar o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"É necesario o contrasinal para reiniciar o dispositivo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Necesítase o padrón para obter seguranza adicional."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Necesítase o PIN para obter seguranza adicional."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Necesítase o contrasinal para obter seguranza adicional."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"É necesario o padrón para cambiar os perfís."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"É necesario o PIN para cambiar os perfís."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"É necesario o contrasinal para cambiar os perfís."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"É necesario o padrón despois do reinicio do dispositivo"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"É necesario o PIN despois do reinicio do dispositivo"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"É necesario o contrasinal despois do reinicio do dispositivo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"É necesario o padrón para obter seguranza adicional"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"É necesario o PIN para obter seguranza adicional"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"É necesario o contrasinal para obter seguranza adicional"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"É necesario o padrón para cambiar os perfís"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"É necesario o PIN para cambiar os perfís"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"É necesario o contrasinal para cambiar os perfís"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">O dispositivo non se desbloqueou durante <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirma o padrón.</item>
       <item quantity="one">O dispositivo non se desbloqueou durante <xliff:g id="NUMBER_0">%d</xliff:g> hora. Confirma o padrón.</item>
diff --git a/packages/Keyguard/res/values-gu-rIN/strings.xml b/packages/Keyguard/res/values-gu-rIN/strings.xml
index 8ab8249..1b346a2 100644
--- a/packages/Keyguard/res/values-gu-rIN/strings.xml
+++ b/packages/Keyguard/res/values-gu-rIN/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="489430505491862444">"જ્યારે તમે ઉપકરણ ફરીથી સેટ કરો ત્યારે પેટર્ન જરૂરી છે."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"જ્યારે તમે ઉપકરણ ફરીથી સેટ કરો ત્યારે PIN જરૂરી છે."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"જ્યારે તમે ઉપકરણ ફરીથી સેટ કરો ત્યારે પાસવર્ડ જરૂરી છે."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"વધારાની સુરક્ષા માટે પેટર્ન જરૂરી છે."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"વધારાની સુરક્ષા માટે PIN જરૂરી છે."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"વધારાની સુરક્ષા માટે પાસવર્ડ જરૂરી છે."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"જ્યારે તમે પ્રોફાઇલ્સ સ્વિચ કરો ત્યારે પેટર્ન જરૂરી છે."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"જ્યારે તમે પ્રોફાઇલ્સ સ્વિચ કરો ત્યારે PIN જરૂરી છે."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"જ્યારે તમે પ્રોફાઇલ્સ સ્વિચ કરો ત્યારે પાસવર્ડ જરૂરી છે."</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="one">ઉપકરણ <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. પેટર્નની પુષ્ટિ કરો.</item>
       <item quantity="other">ઉપકરણ <xliff:g id="NUMBER_1">%d</xliff:g> કલાક માટે અનલૉક કરવામાં આવ્યું નથી. પેટર્નની પુષ્ટિ કરો.</item>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
index 92d2f7a..47aefab 100644
--- a/packages/Keyguard/res/values-hi/strings.xml
+++ b/packages/Keyguard/res/values-hi/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="489430505491862444">"डिवाइस को पुनः प्रारंभ करते समय पैटर्न की आवश्यकता होती है."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"डिवाइस को पुनः प्रारंभ करते समय पिन की आवश्यकता होती है."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"डिवाइस को पुनः प्रारंभ करते समय पासवर्ड की आवश्यकता होती है."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"अतिरिक्‍त सुरक्षा के लिए पैटर्न आवश्‍यक है."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"अतिरिक्‍त सुरक्षा के लिए पिन आवश्‍यक है."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"अतिरिक्‍त सुरक्षा के लिए पासवर्ड आवश्‍यक है."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"प्रोफ़ाइल में स्विच करते समय पैटर्न की आवश्यकता होती है."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"प्रोफ़ाइल में स्विच करते समय पिन की आवश्यकता होती है."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"प्रोफ़ाइल में स्विच करते समय पासवर्ड की आवश्यकता होती है."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"प्रोफ़ाइल में स्विच करते समय पैटर्न की आवश्यकता होती है"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"प्रोफ़ाइल में स्विच करते समय पिन की आवश्यकता होती है"</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="one">डिवाइस <xliff:g id="NUMBER_1">%d</xliff:g> घंटे से अनलॉक नहीं किया गया है. पैटर्न की पुष्टि करें.</item>
       <item quantity="other">डिवाइस <xliff:g id="NUMBER_1">%d</xliff:g> घंटे से अनलॉक नहीं किया गया है. पैटर्न की पुष्टि करें.</item>
diff --git a/packages/Keyguard/res/values-hr/strings.xml b/packages/Keyguard/res/values-hr/strings.xml
index c716746..c65db7f 100644
--- a/packages/Keyguard/res/values-hr/strings.xml
+++ b/packages/Keyguard/res/values-hr/strings.xml
@@ -112,15 +112,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nema usluge."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Gumb za promjenu načina unosa."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Način rada u zrakoplovu"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Za ponovno pokretanje uređaja morate unijeti uzorak."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Za ponovno pokretanje uređaja morate unijeti PIN."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Za ponovno pokretanje uređaja morate unijeti zaporku."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Unesite uzorak radi dodatne sigurnosti."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Unesite PIN radi dodatne sigurnosti."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Unesite zaporku radi dodatne sigurnosti."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Za promjenu profila morate unijeti uzorak."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Za promjenu profila morate unijeti PIN."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Za promjenu profila morate unijeti zaporku."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Nakon ponovnog pokretanja uređaja morate unijeti uzorak"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Nakon ponovnog pokretanja uređaja morate unijeti PIN"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Nakon ponovnog pokretanja uređaja morate unijeti zaporku"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Unesite uzorak radi dodatne sigurnosti"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Unesite PIN radi dodatne sigurnosti"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Unesite zaporku radi dodatne sigurnosti"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Za promjenu profila morate unijeti uzorak"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Za promjenu profila morate unijeti PIN"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Za promjenu profila morate unijeti zaporku"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Uređaj nije bio otključan <xliff:g id="NUMBER_1">%d</xliff:g> sat. Potvrdite uzorak.</item>
       <item quantity="few">Uređaj nije bio otključan <xliff:g id="NUMBER_1">%d</xliff:g> sata. Potvrdite uzorak.</item>
diff --git a/packages/Keyguard/res/values-hu/strings.xml b/packages/Keyguard/res/values-hu/strings.xml
index 2ecfb21..104735d 100644
--- a/packages/Keyguard/res/values-hu/strings.xml
+++ b/packages/Keyguard/res/values-hu/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nincs szolgáltatás."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Beviteli mód váltása gomb."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Repülős üzemmód"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Ha újraindítja az eszközt, meg kell adnia a mintát."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Ha újraindítja az eszközt, meg kell adnia a PIN kódot."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Ha újraindítja az eszközt, meg kell adnia a jelszót."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Minta szükséges a nagyobb biztonság érdekében."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-kód szükséges a nagyobb biztonság érdekében."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Jelszó szükséges a nagyobb biztonság érdekében."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Ha vált a profilok között, meg kell adnia a mintát."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Ha vált a profilok között, meg kell adnia a PIN kódot."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Ha vált a profilok között, meg kell adnia a jelszót."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Az eszköz újraindítását követően meg kell adni a mintát"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Az eszköz újraindítását követően meg kell adni a PIN-kódot"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Az eszköz újraindítását követően meg kell adni a jelszót"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Minta szükséges a nagyobb biztonság érdekében"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN-kód szükséges a nagyobb biztonság érdekében"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Jelszó szükséges a nagyobb biztonság érdekében"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Ha vált a profilok között, meg kell adni a mintát"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Ha vált a profilok között, meg kell adni a PIN-kódot"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Ha vált a profilok között, meg kell adni a jelszót"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Az eszköz zárolása <xliff:g id="NUMBER_1">%d</xliff:g> órája nem lett feloldva. Erősítse meg a mintát.</item>
       <item quantity="one">Az eszköz zárolása <xliff:g id="NUMBER_0">%d</xliff:g> órája nem lett feloldva. Erősítse meg a mintát.</item>
diff --git a/packages/Keyguard/res/values-hy-rAM/strings.xml b/packages/Keyguard/res/values-hy-rAM/strings.xml
index e6692af..0c70508 100644
--- a/packages/Keyguard/res/values-hy-rAM/strings.xml
+++ b/packages/Keyguard/res/values-hy-rAM/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="489430505491862444">"Սարքը վերագործարկելիս անհրաժեշտ է մուտքագրել ապակողպման նախշը:"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Սարքը վերագործարկելիս անհրաժեշտ է մուտքագրել PIN կոդը:"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Սարքը վերագործարկելիս անհրաժեշտ է մուտքագրել գաղտնաբառը:"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Անվտանգության նկատառումներից ելնելով անհրաժեշտ է մուտքագրել նախշը:"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Անվտանգության նկատառումներից ելնելով անհրաժեշտ է մուտքագրել PIN կոդը:"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Անվտանգության նկատառումներից ելնելով անհրաժեշտ է մուտքագրել գաղտնաբառը:"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Պրոֆիլները փոխարկելիս անհրաժեշտ է մուտքագրել ապակողպման նախշը:"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Պրոֆիլները փոխարկելիս անհրաժեշտ է մուտքագրել PIN կոդը:"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Պրոֆիլները փոխարկելիս անհրաժեշտ է մուտքագրել գաղտնաբառը:"</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="one">Սարքը չի ապակողպվել <xliff:g id="NUMBER_1">%d</xliff:g> ժամվա ընթացքում: Հաստատեք նախշը:</item>
       <item quantity="other">Սարքը չի ապակողպվել <xliff:g id="NUMBER_1">%d</xliff:g> ժամվա ընթացքում: Հաստատեք նախշը:</item>
diff --git a/packages/Keyguard/res/values-in/strings.xml b/packages/Keyguard/res/values-in/strings.xml
index 4b18dbc..b409646 100644
--- a/packages/Keyguard/res/values-in/strings.xml
+++ b/packages/Keyguard/res/values-in/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Tidak ada layanan."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tombol beralih metode masukan."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Mode pesawat"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pola diperlukan jika Anda memulai ulang perangkat."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN diperlukan jika Anda memulai ulang perangkat."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Sandi diperlukan jika Anda memulai ulang perangkat."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pola diperlukan untuk keamanan tambahan."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN diperlukan untuk keamanan tambahan."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Sandi diperlukan untuk keamanan tambahan."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Pola diperlukan jika Anda beralih profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN diperlukan jika Anda beralih profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Sandi diperlukan jika Anda beralih profil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Pola diperlukan setelah perangkat dimulai ulang"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN diperlukan setelah perangkat dimulai ulang"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Sandi diperlukan setelah perangkat dimulai ulang"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Pola diperlukan untuk keamanan tambahan"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN diperlukan untuk keamanan tambahan"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Sandi diperlukan untuk keamanan tambahan"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Pola diperlukan jika Anda beralih profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN diperlukan jika Anda beralih profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Sandi diperlukan jika Anda beralih profil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Perangkat belum dibuka kuncinya selama <xliff:g id="NUMBER_1">%d</xliff:g> jam. Konfirmasi pola.</item>
       <item quantity="one">Perangkat belum dibuka kuncinya selama <xliff:g id="NUMBER_0">%d</xliff:g> jam. Konfirmasi pola.</item>
diff --git a/packages/Keyguard/res/values-is-rIS/strings.xml b/packages/Keyguard/res/values-is-rIS/strings.xml
index 4b8b702..53c33f0 100644
--- a/packages/Keyguard/res/values-is-rIS/strings.xml
+++ b/packages/Keyguard/res/values-is-rIS/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ekkert símasamband."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Hnappur til að skipta um innsláttaraðferð."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Flugstilling"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Mynsturs er krafist þegar þú endurræsir tækið."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN-númers er krafist þegar þú endurræsir tækið."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Aðgangsorðs er krafist þegar þú endurræsir tækið."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mynsturs er krafist af öryggisástæðum."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-númers er krafist af öryggisástæðum."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Aðgangsorðs er krafist af öryggisástæðum."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Mynsturs er krafist þegar þú skiptir um snið."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN-númers er krafist þegar þú skiptir um snið."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Aðgangsorðs er krafist þegar þú skiptir um snið."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Mynsturs er krafist þegar tækið er endurræst"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN-númers er krafist þegar tækið er endurræst"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Aðgangsorðs er krafist þegar tækið er endurræst"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Mynsturs er krafist af öryggisástæðum"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN-númers er krafist af öryggisástæðum"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Aðgangsorðs er krafist af öryggisástæðum"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Mynsturs er krafist þegar þú skiptir um snið"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN-númers er krafist þegar þú skiptir um snið"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Aðgangsorðs er krafist þegar þú skiptir um snið"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Tækið hefur ekki verið tekið úr lás í <xliff:g id="NUMBER_1">%d</xliff:g> klukkustund. Staðfestu mynstrið.</item>
       <item quantity="other">Tækið hefur ekki verið tekið úr lás í <xliff:g id="NUMBER_1">%d</xliff:g> klukkustundir. Staðfestu mynstrið.</item>
diff --git a/packages/Keyguard/res/values-it/strings.xml b/packages/Keyguard/res/values-it/strings.xml
index 08d4116..6ede2f9 100644
--- a/packages/Keyguard/res/values-it/strings.xml
+++ b/packages/Keyguard/res/values-it/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nessun servizio."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Pulsante per cambiare metodo di immissione."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modalità aereo"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Sequenza obbligatoria dopo il riavvio del dispositivo."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN obbligatorio dopo il riavvio del dispositivo."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Password obbligatoria dopo il riavvio del dispositivo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pattern obbligatorio per una maggiore sicurezza."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN obbligatorio per una maggiore sicurezza."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Password obbligatoria per una maggiore sicurezza."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Sequenza obbligatoria dopo aver cambiato profilo."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN obbligatorio dopo aver cambiato profilo."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Password obbligatoria dopo aver cambiato profilo."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Sequenza obbligatoria dopo il riavvio del dispositivo"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN obbligatorio dopo il riavvio del dispositivo"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Password obbligatoria dopo il riavvio del dispositivo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Sequenza obbligatoria per maggiore sicurezza"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN obbligatorio per maggiore sicurezza"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Password obbligatoria per maggiore sicurezza"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Sequenza obbligatoria dopo aver cambiato profilo"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN obbligatorio dopo aver cambiato profilo"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Password obbligatoria dopo aver cambiato profilo"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Il dispositivo non viene sbloccato da <xliff:g id="NUMBER_1">%d</xliff:g> ore. Conferma la sequenza.</item>
       <item quantity="one">Il dispositivo non viene sbloccato da <xliff:g id="NUMBER_0">%d</xliff:g> ora. Conferma la sequenza.</item>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
index b9cdf5e..43ff724 100644
--- a/packages/Keyguard/res/values-iw/strings.xml
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -114,15 +114,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="489430505491862444">"יש להזין את קו ביטול הנעילה לאחר אתחול המכשיר."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"‏יש להזין את ה-PIN לאחר אתחול המכשיר."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"יש להזין את הסיסמה לאחר אתחול המכשיר."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"יש להזין את קו ביטול הנעילה על מנת להגביר את רמת האבטחה."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"‏יש להזין PIN על מנת להגביר את רמת האבטחה."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"יש להזין סיסמה על מנת להגביר את רמת האבטחה."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"יש להזין את קו ביטול הנעילה בעת מעבר בין פרופילים."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"‏יש להזין את ה-PIN בעת מעבר בין פרופילים."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"יש להזין את הסיסמה בעת מעבר בין פרופילים."</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="two">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. אשר את קו ביטול הנעילה.</item>
       <item quantity="many">נעילת המכשיר לא בוטלה במשך <xliff:g id="NUMBER_1">%d</xliff:g> שעות. אשר את קו ביטול הנעילה.</item>
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
index adfefcb..503e18e 100644
--- a/packages/Keyguard/res/values-ja/strings.xml
+++ b/packages/Keyguard/res/values-ja/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="489430505491862444">"端末を再起動した時にはパターンが必要です。"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"端末を再起動した時にはPINが必要です。"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"端末を再起動した時にはパスワードが必要です。"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"セキュリティを強化するため、パターンが必要です。"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"セキュリティを強化するため、PINが必要です。"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"セキュリティを強化するため、パスワードが必要です。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"プロファイルを切り替えるにはパターンが必要です。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"プロファイルを切り替えるにはPINが必要です。"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"プロファイルを切り替えるにはパスワードが必要です。"</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>時間、解除されていません。パターンを確認してください。</item>
       <item quantity="one">端末のロックが<xliff:g id="NUMBER_0">%d</xliff:g>時間、解除されていません。パターンを確認してください。</item>
diff --git a/packages/Keyguard/res/values-ka-rGE/strings.xml b/packages/Keyguard/res/values-ka-rGE/strings.xml
index 78fc54b..2fdd668 100644
--- a/packages/Keyguard/res/values-ka-rGE/strings.xml
+++ b/packages/Keyguard/res/values-ka-rGE/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="489430505491862444">"ნიმუში საჭიროა მოწყობილობის გადატვირთვისას."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN-კოდი საჭიროა მოწყობილობის გადატვირთვისას."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"პაროლი საჭიროა მოწყობილობის გადატვირთვისას."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ნიმუშია საჭირო დამატებითი უსაფრთხოებისთვის."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-კოდია საჭირო დამატებითი უსაფრთხოებისთვის."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"პაროლია საჭირო დამატებითი უსაფრთხოებისთვის."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ნიმუში საჭიროა პროფილების გადართვისას."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN-კოდი საჭიროა პროფილების გადართვისას."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"პაროლი საჭიროა პროფილების გადართვისას."</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> საათის განმავლობაში. დაადასტურეთ ნიმუში.</item>
       <item quantity="one">მოწყობილობა არ განბლოკილა <xliff:g id="NUMBER_0">%d</xliff:g> საათის განმავლობაში. დაადასტურეთ ნიმუში.</item>
diff --git a/packages/Keyguard/res/values-kk-rKZ/strings.xml b/packages/Keyguard/res/values-kk-rKZ/strings.xml
index 0d415ff..fd5cf93 100644
--- a/packages/Keyguard/res/values-kk-rKZ/strings.xml
+++ b/packages/Keyguard/res/values-kk-rKZ/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="489430505491862444">"Құрылғыны өшіріп, қайта қосқанда, өрнекті енгізу қажет."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Құрылғыны өшіріп, қайта қосқанда, PIN кодын енгізу қажет."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Құрылғыны өшіріп, қайта қосқанда, құпия сөзді енгізу қажет."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Қосымша қауіпсіздік үшін өрнек қажет."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Қосымша қауіпсіздік үшін PIN коды қажет."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Қосымша қауіпсіздік үшін құпия сөз қажет."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Профильдерді ауыстырғанда, өрнекті енгізу қажет."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Профильдерді ауыстырғанда, PIN кодын енгізу қажет."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Профильдерді ауыстырғанда, құпия сөзді енгізу қажет."</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> сағат бойы ашылмады. Өрнекті растаңыз.</item>
       <item quantity="one">Құрылғы құлпы <xliff:g id="NUMBER_0">%d</xliff:g> сағат бойы ашылмады. Өрнекті растаңыз.</item>
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
index 1967246..2da8370 100644
--- a/packages/Keyguard/res/values-km-rKH/strings.xml
+++ b/packages/Keyguard/res/values-km-rKH/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="489430505491862444">"តម្រូវឲ្យមានលំនាំនៅពេលដែលអ្នកចាប់ផ្តើមឧបករណ៍ឡើងវិញ។"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"តម្រូវឲ្យមានកូដ PIN នៅពេលដែលអ្នកចាប់ផ្តើមឧបករណ៍ឡើងវិញ។"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"តម្រូវឲ្យមានពាក្យសម្ងាត់នៅពេលដែលអ្នកចាប់ផ្តើមឧបករណ៍ឡើងវិញ។"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"តម្រូវឲ្យមានលំនាំសម្រាប់សវុត្ថិភាពបន្ថែម"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"តម្រូវឲ្យមានកូដ PIN សម្រាប់សុវត្ថិភាពបន្ថែម"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"តម្រូវឲ្យមានពាក្យសម្ងាត់សម្រាប់សុវត្ថិភាពបន្ថែម"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"តម្រូវឲ្យមានលំនាំនៅពេលដែលអ្នកប្តូរប្រវត្តិរូបរបស់អ្នក។"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"តម្រូវឲ្យមានកូដ PIN នៅពេលដែលអ្នកប្តូរប្រវត្តិរូបរបស់អ្នក។"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"តម្រូវឲ្យមានពាក្យសម្ងាត់នៅពេលដែលអ្នកប្តូរប្រវត្តិរូបរបស់អ្នក។"</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> ម៉ោងហើយ។ បញ្ជាប់លំនាំ។</item>
       <item quantity="one">ឧបករណ៍មិនបានដោះសោអស់រយៈពេល <xliff:g id="NUMBER_0">%d</xliff:g> ម៉ោងហើយ។ បញ្ជាក់លំនាំ។</item>
diff --git a/packages/Keyguard/res/values-kn-rIN/strings.xml b/packages/Keyguard/res/values-kn-rIN/strings.xml
index 3ad18c3..31deb66 100644
--- a/packages/Keyguard/res/values-kn-rIN/strings.xml
+++ b/packages/Keyguard/res/values-kn-rIN/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="489430505491862444">"ನೀವು ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ನೀವು ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ಪಿನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ನೀವು ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಾಗ ಪಾಸ್‌ವರ್ಡ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಗೆ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿದೆ."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಗೆ ಪಿನ್ ಅಗತ್ಯವಿದೆ."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಗಾಗಿ ಪಾಸ್‌ವರ್ಡ್ ಅಗತ್ಯವಿದೆ."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ನೀವು ಪ್ರೊಫೈಲ್ ಬದಲಾಯಿಸಿದಾಗ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ನೀವು ಪ್ರೊಫೈಲ್ ಬದಲಾಯಿಸಿದಾಗ ಪಿನ್ ಅಗತ್ಯವಿರುತ್ತದೆ."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ನೀವು ಪ್ರೊಫೈಲ್ ಬದಲಾಯಿಸಿದಾಗ ಪಾಸ್‌ವರ್ಡ್‌ ಅಗತ್ಯವಿರುತ್ತದೆ."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"ನೀವು ಪ್ರೊಫೈಲ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಿದಾಗ ಪ್ಯಾಟರ್ನ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"ನೀವು ಪ್ರೊಫೈಲ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಿದಾಗ ಪಿನ್ ಅಗತ್ಯವಿರುತ್ತದೆ"</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="one">ಸಾಧನವನ್ನು <xliff:g id="NUMBER_1">%d</xliff:g> ಗಂಟೆಗಳ ಕಾಲ ಅನ್‌ಲಾಕ್‌ ಮಾಡಲಾಗಿಲ್ಲ. ನಮೂನೆಯನ್ನು ಖಚಿತಪಡಿಸಿ.</item>
       <item quantity="other">ಸಾಧನವನ್ನು <xliff:g id="NUMBER_1">%d</xliff:g> ಗಂಟೆಗಳ ಕಾಲ ಅನ್‌ಲಾಕ್‌ ಮಾಡಲಾಗಿಲ್ಲ. ನಮೂನೆಯನ್ನು ಖಚಿತಪಡಿಸಿ.</item>
diff --git a/packages/Keyguard/res/values-ko/strings.xml b/packages/Keyguard/res/values-ko/strings.xml
index a85f03d..67d6acb 100644
--- a/packages/Keyguard/res/values-ko/strings.xml
+++ b/packages/Keyguard/res/values-ko/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="489430505491862444">"기기를 다시 시작하려면 패턴이 필요합니다."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"기기를 다시 시작하려면 PIN이 필요합니다."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"기기를 다시 시작하려면 비밀번호가 필요합니다."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"보안 강화를 위해 패턴이 필요합니다."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"보안 강화를 위해 PIN이 필요합니다."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"보안 강화를 위해 비밀번호가 필요합니다."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"프로필을 전환하려면 패턴이 필요합니다."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"프로필을 전환하려면 PIN이 필요합니다."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"프로필을 전환하려면 비밀번호가 필요합니다."</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>시간 이상 기기가 잠금 해제되지 않았습니다. 패턴을 확인하세요.</item>
       <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g>시간 이상 기기가 잠금 해제되지 않았습니다. 패턴을 확인하세요.</item>
diff --git a/packages/Keyguard/res/values-ky-rKG/strings.xml b/packages/Keyguard/res/values-ky-rKG/strings.xml
index 6e6394e..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="489430505491862444">"Түзмөктү өчүрүп-күйгүзгөнүңүздө сүрөт үлгүсү керектелет."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Түзмөктү өчүрүп-күйгүзгөнүңүздө PIN керектелет."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Түзмөктү өчүрүп-күйгүзгөнүңүздө сырсөз керектелет."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Кошумча коопсуздук үчүн сүрөт үлгүсү керек."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Кошумча коопсуздук үчүн PIN код керек."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Кошумча коопсуздук үчүн сырсөз керек."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Профилдерди которгонуңузда сүрөт үлгүсү керектелет."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Профилдерди которгонуңузда PIN керектелет."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Профилдерди которгонуңузда сырсөз керектелет."</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-lo-rLA/strings.xml b/packages/Keyguard/res/values-lo-rLA/strings.xml
index e92907a..e99b22d 100644
--- a/packages/Keyguard/res/values-lo-rLA/strings.xml
+++ b/packages/Keyguard/res/values-lo-rLA/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="489430505491862444">"ຈຳເປັນຕ້ອງມີແບບຮູບ ເມື່ອທ່ານເລີ່ມລະບົບອຸປະກອນໃໝ່."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ຈຳເປັນຕ້ອງມີ PIN ເມື່ອທ່ານເລີ່ມລະບົບອຸປະກອນໃໝ່."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ຈຳເປັນຕ້ອງມີລະຫັດຜ່ານ ເມື່ອທ່ານເລີ່ມລະບົບອຸປະກອນໃໝ່."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ຈຳ​ເປັນ​ຕ້ອງ​ມີ​ຮູບ​ແບບ​ສຳ​ລັບ​ຄວາມ​ປອດ​ໄພ​ເພີ່ມ​ເຕີມ."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ຈຳ​ເປັນ​ຕ້ອງ​ມີ PIN ​ສຳ​ລັບ​ຄວາມ​ປອດ​ໄພ​ເພີ່ມ​ເຕີມ."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ຈຳ​ເປັນ​ຕ້ອງ​ມີ​ລະ​ຫັດ​ຜ່ານ​ສຳ​ລັບ​ຄວາມ​ປອດ​ໄພ​ເພີ່ມ​ເຕີມ."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ຈຳເປັນຕ້ອງມີແບບຮູບ ເມື່ອທ່ານປ່ຽນໂປຣໄຟລ໌."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ຈຳເປັນຕ້ອງມີ PIN ເມື່ອທ່ານປ່ຽນໂປຣໄຟລ໌."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ຈຳເປັນຕ້ອງມີລະຫັດຜ່ານ ເມື່ອທ່ານປ່ຽນໂປຣໄຟລ໌."</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> ຊົ່ວໂມງ. ຢືນ​ຢັນ​​ແບບຮູບ​.</item>
       <item quantity="one">ອຸປະກອນບໍ່ໄດ້ຖືກປົດລັອກເປັນເວລາ <xliff:g id="NUMBER_0">%d</xliff:g> ຊົ່ວໂມງ. ຢືນຢັນແບບຮູບ.</item>
diff --git a/packages/Keyguard/res/values-lt/strings.xml b/packages/Keyguard/res/values-lt/strings.xml
index e647795..fd83ece 100644
--- a/packages/Keyguard/res/values-lt/strings.xml
+++ b/packages/Keyguard/res/values-lt/strings.xml
@@ -114,15 +114,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nėra paslaugos."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Perjungti įvesties metodo mygtuką."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Lėktuvo režimas"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Iš naujo paleidus įrenginį reikalingas atrakinimo piešinys."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Iš naujo paleidus įrenginį reikalingas PIN kodas."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Iš naujo paleidus įrenginį reikalingas slaptažodis."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Norint užtikrinti papildomą saugumą būtinas atrakinimo piešinys."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Norint užtikrinti papildomą saugumą būtinas PIN kodas."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Norint užtikrinti papildomą saugumą būtinas slaptažodis."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Perjungiant profilius reikalingas atrakinimo piešinys."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Perjungiant profilius reikalingas PIN kodas."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Perjungiant profilius reikalingas slaptažodis."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Iš naujo paleidus įrenginį būtinas atrakinimo piešinys"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Iš naujo paleidus įrenginį būtinas PIN kodas"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Iš naujo paleidus įrenginį būtinas slaptažodis"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Norint užtikrinti papildomą saugumą būtinas atrakinimo piešinys"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Norint užtikrinti papildomą saugumą būtinas PIN kodas"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Norint užtikrinti papildomą saugumą būtinas slaptažodis"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Perjungiant profilius būtinas atrakinimo piešinys"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Perjungiant profilius būtinas PIN kodas"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Perjungiant profilius būtinas slaptažodis"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Įrenginys nebuvo atrakintas <xliff:g id="NUMBER_1">%d</xliff:g> valandą. Patvirtinkite atrakinimo piešinį.</item>
       <item quantity="few">Įrenginys nebuvo atrakintas <xliff:g id="NUMBER_1">%d</xliff:g> valandas. Patvirtinkite atrakinimo piešinį.</item>
diff --git a/packages/Keyguard/res/values-lv/strings.xml b/packages/Keyguard/res/values-lv/strings.xml
index 2ce1676..5a35912 100644
--- a/packages/Keyguard/res/values-lv/strings.xml
+++ b/packages/Keyguard/res/values-lv/strings.xml
@@ -112,15 +112,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nav pakalpojuma."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ievades metodes maiņas poga."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Lidojuma režīms"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Restartējot ierīci, ir jāievada kombinācija."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Restartējot ierīci, ir jāievada PIN."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Restartējot ierīci, ir jāievada parole."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Papildu drošībai nepieciešama atbloķēšanas kombinācija."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Papildu drošībai nepieciešams PIN kods."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Papildu drošībai nepieciešama parole."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Mainot profilu, ir jāievada kombinācija."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Mainot profilu, ir jāievada PIN."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Mainot profilu, ir jāievada parole."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Pēc ierīces restartēšanas ir jāievada atbloķēšanas kombinācija."</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Pēc ierīces restartēšanas ir jāievada PIN kods."</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Pēc ierīces restartēšanas ir jāievada parole."</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Papildu drošībai ir nepieciešama atbloķēšanas kombinācija."</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Papildu drošībai ir nepieciešams PIN kods."</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Papildu drošībai ir nepieciešama parole."</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Pārslēdzot profilus, ir jāievada atbloķēšanas kombinācija."</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Pārslēdzot profilus, ir jāievada PIN kods."</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Pārslēdzot profilus, ir jāievada parole."</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="zero">Ierīce nav tikusi atbloķēta <xliff:g id="NUMBER_1">%d</xliff:g> stundas. Apstipriniet kombināciju.</item>
       <item quantity="one">Ierīce nav tikusi atbloķēta <xliff:g id="NUMBER_1">%d</xliff:g> stundu. Apstipriniet kombināciju.</item>
diff --git a/packages/Keyguard/res/values-mk-rMK/strings.xml b/packages/Keyguard/res/values-mk-rMK/strings.xml
index adbdd70..a1e224d 100644
--- a/packages/Keyguard/res/values-mk-rMK/strings.xml
+++ b/packages/Keyguard/res/values-mk-rMK/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="489430505491862444">"Потребна е шема кога го престартувате уредот."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Потребен е ПИН кога го престартувате уредот."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Потребна е лозинка кога го престартувате уредот."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Потребна е шема за дополнителна безбедност."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Потребен е ПИН за дополнителна безбедност."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Потребна е лозинка за дополнителна безбедност."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Потребна е шема кога променувате профили."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Потребен е ПИН кога променувате профили."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Потребна е лозинка кога променувате профили."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Потребна е шема кога променувате профили"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Потребен е ПИН-код кога променувате профили"</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="one">Уредот не е отклучен за <xliff:g id="NUMBER_1">%d</xliff:g> час. Потврдете ја шемата.</item>
       <item quantity="other">Уредот не е отклучен за <xliff:g id="NUMBER_1">%d</xliff:g> часа. Потврдете ја шемата.</item>
diff --git a/packages/Keyguard/res/values-ml-rIN/strings.xml b/packages/Keyguard/res/values-ml-rIN/strings.xml
index a528e69..3a898d8 100644
--- a/packages/Keyguard/res/values-ml-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ml-rIN/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="489430505491862444">"ഉപകരണം പുനഃരാരംഭിക്കുമ്പോൾ പാറ്റേൺ ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ഉപകരണം പുനഃരാരംഭിക്കുമ്പോൾ PIN ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ഉപകരണം പുനഃരാരംഭിക്കുമ്പോൾ പാസ്‌വേഡ് ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"അധിക സുരക്ഷയ്ക്ക് പാറ്റേൺ ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"അധിക സുരക്ഷയ്ക്ക് PIN ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"അധിക സുരക്ഷയ്ക്ക് പാസ്‌വേഡ് ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ പാറ്റേൺ ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ PIN ആവശ്യമാണ്."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ പാസ്‌വേഡ് ആവശ്യമാണ്."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ പാറ്റേൺ ആവശ്യമാണ്"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"പ്രൊഫൈലുകൾ തമ്മിൽ മാറുമ്പോൾ പിൻ ആവശ്യമാണ്"</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>
diff --git a/packages/Keyguard/res/values-mn-rMN/strings.xml b/packages/Keyguard/res/values-mn-rMN/strings.xml
index 1749a71..410ec4b 100644
--- a/packages/Keyguard/res/values-mn-rMN/strings.xml
+++ b/packages/Keyguard/res/values-mn-rMN/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="489430505491862444">"Төхөөрөмжийг дахин эхлүүлэхийн тулд зурган хээ шаардлагатай."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Төхөөрөмжийг дахин эхлүүлэхийн тулд PIN шаардлагатай."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Төхөөрөмжийг дахин эхлүүлэхийн тулд нууц үг шаардлагатай."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Аюулгүй байдлын үүднээс зурган түгжээ оруулах шаардлагатай."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Аюулгүй байдлын үүднээс PIN оруулах шаардлагатай."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Аюулгүй байдлын үүднээс нууц үг оруулах шаардлагатай."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Профайлыг солихын тулд зурган хээ шаардлагатай."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Профайлыг солихын тулд PIN шаардлагатай."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Профайлыг солих үед нууц үг шаардлагатай."</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> цагийн турш тайлаагүй байна. Зурган хээг баталгаажуулна уу.</item>
       <item quantity="one">Төхөөрөмжийн түгжээг <xliff:g id="NUMBER_0">%d</xliff:g> цагийн турш тайлаагүй байна. Зурган хээг баталгаажуулна уу.</item>
diff --git a/packages/Keyguard/res/values-mr-rIN/strings.xml b/packages/Keyguard/res/values-mr-rIN/strings.xml
index 9452fe7..0418a7b 100644
--- a/packages/Keyguard/res/values-mr-rIN/strings.xml
+++ b/packages/Keyguard/res/values-mr-rIN/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="489430505491862444">"आपण डिव्‍हाइस रीस्टार्ट करता तेव्‍हा नुमन्याची आवश्‍यकता असते."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"आपण डिव्‍हाइस रीस्टार्ट करता तेव्‍हा पिन ची आवश्‍यकता असते."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"आपण डिव्‍हाइस रीस्टार्ट करता तेव्‍हा संकेतशब्दाची आवश्‍यकता असते."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"अतिरिक्त सुरक्षिततेसाठी नमुना आवश्‍यक आहे."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"अतिरिक्त सुरक्षिततेसाठी पिन आवश्‍यक आहे."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"अतिरिक्त सुरक्षिततेसाठी संकेतशब्द आवश्‍यक आहे."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"आपण प्रोफाईल स्विच करता तेव्‍हा नमुन्याची आवश्‍यकता असते."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"आपण प्रोफाईल स्विच करता तेव्‍हा पिन ची आवश्‍यकता असते."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"आपण प्रोफाईल स्विच करता तेव्‍हा संकेतशब्दाची आवश्‍यकता असते."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"आपण प्रोफाईल स्विच करता तेव्‍हा नमुना आवश्‍यक आहे"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"आपण प्रोफाईल स्विच करता तेव्‍हा पिन आवश्‍यक आहे"</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="one">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासासाठी अनलॉक केले गेले नाही. नमुन्याची पुष्टी करा.</item>
       <item quantity="other">डिव्‍हाइस <xliff:g id="NUMBER_1">%d</xliff:g> तासांसाठी अनलॉक केले गेले नाही. नमुन्याची पुष्टी करा.</item>
diff --git a/packages/Keyguard/res/values-ms-rMY/strings.xml b/packages/Keyguard/res/values-ms-rMY/strings.xml
index 9b68c5c..e8c0bab 100644
--- a/packages/Keyguard/res/values-ms-rMY/strings.xml
+++ b/packages/Keyguard/res/values-ms-rMY/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Tiada perkhidmatan."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Butang tukar kaedah input."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Mod Pesawat"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Corak diperlukan apabila anda memulakan semula peranti."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN diperlukan apabila anda memulakan semula peranti."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Kata laluan diperlukan apabila anda memulakan semula peranti."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Corak diperlukan untuk keselamatan tambahan."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN diperlukan untuk keselamatan tambahan."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Kata laluan diperlukan untuk keselamatan tambahan."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Corak diperlukan apabila anda menukar profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN diperlukan apabila anda menukar profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Kata laluan diperlukan apabila anda menukar profil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Corak diperlukan setelah peranti dimulakan semula"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN diperlukan setelah peranti dimulakan semula"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Kata laluan diperlukan setelah peranti dimulakan semula"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Corak diperlukan untuk keselamatan tambahan"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN diperlukan untuk keselamatan tambahan"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Kata laluan diperlukan untuk keselamatan tambahan"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Corak diperlukan apabila anda menukar profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN diperlukan apabila anda menukar profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Kata laluan diperlukan apabila anda menukar profil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Peranti tidak dibuka kuncinya selama <xliff:g id="NUMBER_1">%d</xliff:g> jam. Sahkan corak.</item>
       <item quantity="one">Peranti tidak dibuka kuncinya selama <xliff:g id="NUMBER_0">%d</xliff:g> jam. Sahkan corak.</item>
diff --git a/packages/Keyguard/res/values-my-rMM/strings.xml b/packages/Keyguard/res/values-my-rMM/strings.xml
index cb6eb97..86c6e78 100644
--- a/packages/Keyguard/res/values-my-rMM/strings.xml
+++ b/packages/Keyguard/res/values-my-rMM/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="489430505491862444">"သင့် စက်ကိရိယာအား ပြန်စဖွင့်လျှင် ပုံစံ လို၏။"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"သင့် စက်ကိရိယာအား ပြန်စဖွင့်လျှင် PIN လို၏။"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"သင့် စက်ကိရိယာအား ပြန်စဖွင့်လျှင် စကားဝှက် လို၏။"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ပိုပြီး လုံခြုံရန် ပုံစံ လိုအပ်တယ်။"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ပိုပြီး လုံခြုံရန် ပင်နံပါတ် လိုအပ်တယ်။"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ပိုပြီး လုံခြုံရန် စကားဝှက် လိုအပ်တယ်။"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ပရိုဖိုင်းများ သင်ပြောင်းလျှင် ပုံစံ လို၏။"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ပရိုဖိုင်းများ သင်ပြောင်းလျှင် PIN လို၏။"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ပရိုဖိုင်းများ သင်ပြောင်းလျှင် စကားဝှက် လို၏။"</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> နာရီကြာ သော့ပိတ်ထား၏။ ပုံစံအား အတည်ပြုပါ။</item>
       <item quantity="one">စက်ကိရိယာအား <xliff:g id="NUMBER_0">%d</xliff:g> နာရီကြာ သော့ပိတ်ထား၏။ ပုံစံအား အတည်ပြုပါ။</item>
diff --git a/packages/Keyguard/res/values-nb/strings.xml b/packages/Keyguard/res/values-nb/strings.xml
index fabda4b..a31c52c 100644
--- a/packages/Keyguard/res/values-nb/strings.xml
+++ b/packages/Keyguard/res/values-nb/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ingen tjeneste."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bytt knapp for inndatametode."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Flymodus"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Du må tegne mønsteret ditt når du starter enheten på nytt."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Du må skrive inn PIN-koden din når du starter enheten på nytt."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Du må skrive inn passordet ditt når du starter enheten på nytt."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mønsteret kreves for ekstra sikkerhet."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN-koden kreves for ekstra sikkerhet."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Passordet kreves for ekstra sikkerhet."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Du må tegne mønsteret ditt når du bytter profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Du må skrive inn PIN-koden din når du bytter profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Du må skrive inn passordet ditt når du bytter profil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Du må tegne mønsteret etter at enheten har startet på nytt"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Du må skrive inn PIN-koden etter at enheten har startet på nytt"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Du må skrive inn passordet etter at enheten har startet på nytt"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Du må tegne mønsteret for ekstra sikkerhet"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Du må skrive inn PIN-koden for ekstra sikkerhet"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Du må skrive inn passordet for ekstra sikkerhet"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Du må tegne mønsteret når du bytter profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Du må skrive inn PIN-koden når du bytter profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Du må skrive inn passordet når du bytter profil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Enheten er ikke blitt låst opp de siste <xliff:g id="NUMBER_1">%d</xliff:g> timene. Bekreft mønsteret.</item>
       <item quantity="one">Enheten er ikke blitt låst opp den siste <xliff:g id="NUMBER_0">%d</xliff:g> timen. Bekreft mønsteret.</item>
diff --git a/packages/Keyguard/res/values-ne-rNP/strings.xml b/packages/Keyguard/res/values-ne-rNP/strings.xml
index 2f9cb6e..5a3b7ec 100644
--- a/packages/Keyguard/res/values-ne-rNP/strings.xml
+++ b/packages/Keyguard/res/values-ne-rNP/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="489430505491862444">"यन्त्र पुन:सुरू गर्न तपाईँलाई ढाँचा चाहिन्छ।"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"यन्त्र पुन:सुरू गर्न तपाईँलाई PIN चाहिन्छ।"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"यन्त्र पुन:सुरू गर्न तपाईँलाई पासवर्ड चाहिन्छ।"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"अतिरिक्त सुरक्षाको लागि ढाँचा आवश्यक छ।"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"अतिरिक्त सुरक्षाको लागि PIN आवश्यक छ।"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"अतिरिक्त सुरक्षाको लागि पासवर्ड आवश्यक छ।"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"प्रोफाइल फेर्न तपाईँलाई ढाँचा चाहिन्छ।"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"प्रोफाइल फेर्न तपाईँलाई PIN चाहिन्छ।"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"प्रोफाइल फेर्न तपाईँलाई पासवर्ड चाहिन्छ।"</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> घन्टा देखि अनलक भएको छैन। ढाँचा पुष्टि गर्नुहोस्।</item>
       <item quantity="one"> यन्त्र <xliff:g id="NUMBER_0">%d</xliff:g> घन्टा देखि अनलक भएको छैन। ढाँचा पुष्टि गर्नुहोस्। </item>
diff --git a/packages/Keyguard/res/values-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml
index 3960fc2..8ded2e8 100644
--- a/packages/Keyguard/res/values-nl/strings.xml
+++ b/packages/Keyguard/res/values-nl/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Geen service"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knop voor wijzigen invoermethode."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Vliegtuigmodus"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Patroon is vereist wanneer u het apparaat opnieuw opstart."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Pincode is vereist wanneer u het apparaat opnieuw opstart."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Wachtwoord is vereist wanneer u het apparaat opnieuw opstart."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Patroon vereist voor extra beveiliging."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Pincode vereist voor extra beveiliging."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Wachtwoord vereist voor extra beveiliging."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Patroon is vereist wanneer u schakelt tussen profielen."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Pincode is vereist wanneer u schakelt tussen profielen."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Wachtwoord is vereist wanneer u schakelt tussen profielen."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Patroon vereist nadat het apparaat opnieuw is opgestart"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Pincode vereist nadat het apparaat opnieuw is opgestart"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Wachtwoord vereist nadat het apparaat opnieuw is opgestart"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Patroon vereist voor extra beveiliging"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Pincode vereist voor extra beveiliging"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Wachtwoord vereist voor extra beveiliging"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Patroon is vereist wanneer je schakelt tussen profielen"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Pincode is vereist wanneer je schakelt tussen profielen"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Wachtwoord is vereist wanneer je schakelt tussen profielen"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Apparaat is al <xliff:g id="NUMBER_1">%d</xliff:g> uur niet ontgrendeld. Bevestig het patroon.</item>
       <item quantity="one">Apparaat is al <xliff:g id="NUMBER_0">%d</xliff:g> uur niet ontgrendeld. Bevestig het patroon.</item>
diff --git a/packages/Keyguard/res/values-pa-rIN/strings.xml b/packages/Keyguard/res/values-pa-rIN/strings.xml
index 2deed85..e867df2 100644
--- a/packages/Keyguard/res/values-pa-rIN/strings.xml
+++ b/packages/Keyguard/res/values-pa-rIN/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="489430505491862444">"ਜਦੋਂ ਤੁਸੀਂ ਡਿਵਾਈਸ ਨੂੰ ਰੀਸਟਾਰਟ ਕਰਦੇ ਹੋ ਤਾਂ ਪੈਟਰਨ ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ਜਦੋਂ ਤੁਸੀਂ ਡਿਵਾਈਸ ਨੂੰ ਰੀਸਟਾਰਟ ਕਰਦੇ ਹੋ ਤਾਂ PIN  ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ਜਦੋਂ ਤੁਸੀਂ ਡਿਵਾਈਸ ਨੂੰ ਰੀਸਟਾਰਟ ਕਰਦੇ ਹੋ ਤਾਂ ਪਾਸਵਰਡ ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ਵਾਧੂ ਸੁਰੱਖਿਆ ਲਈ ਪੈਟਰਨ ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ਵਾਧੂ ਸੁਰੱਖਿਆ ਲਈ PIN ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ਵਾਧੂ ਸੁਰੱਖਿਆ ਲਈ ਪਾਸਵਰਡ ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ਜਦੋਂ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਸਵਿਚ ਕਰਦੇ ਹੋ ਤਾਂ ਪੈਟਰਨ ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ਜਦੋਂ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਸਵਿਚ ਕਰਦੇ ਹੋ ਤਾਂ PIN ਲੁੜੀਂਦਾ ਹੈ।"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ਜਦੋਂ ਤੁਸੀਂ ਪ੍ਰੋਫਾਈਲਾਂ ਸਵਿਚ ਕਰਦੇ ਹੋ ਤਾਂ ਪਾਸਵਰਡ ਲੁੜੀਂਦਾ ਹੈ।"</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="one">ਡਿਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। ਪੈਟਰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
       <item quantity="other">ਡਿਵਾਈਸ <xliff:g id="NUMBER_1">%d</xliff:g> ਘੰਟਿਆਂ ਤੋਂ ਅਨਲੌਕ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। ਪੈਟਰਨ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।</item>
diff --git a/packages/Keyguard/res/values-pl/strings.xml b/packages/Keyguard/res/values-pl/strings.xml
index 53c3d60f..3bd9caf 100644
--- a/packages/Keyguard/res/values-pl/strings.xml
+++ b/packages/Keyguard/res/values-pl/strings.xml
@@ -114,15 +114,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Brak usługi."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Przycisk przełączania metody wprowadzania."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Tryb samolotowy"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Po ponownym uruchomieniu urządzenia wymagany jest wzór."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Po ponownym uruchomieniu urządzenia wymagany jest kod PIN."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Po ponownym uruchomieniu urządzenia wymagane jest hasło."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Dla dodatkowego bezpieczeństwa musisz narysować wzór."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Dla dodatkowego bezpieczeństwa musisz podać kod PIN."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Dla dodatkowego bezpieczeństwa musisz podać hasło."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po przełączeniu profili wymagany jest wzór."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po przełączeniu profili wymagany jest kod PIN."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po przełączeniu profili wymagane jest hasło."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Po ponownym uruchomieniu urządzenia wymagany jest wzór"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Po ponownym uruchomieniu urządzenia wymagany jest kod PIN"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Po ponownym uruchomieniu urządzenia wymagane jest hasło"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Dla dodatkowego bezpieczeństwa musisz narysować wzór"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Dla dodatkowego bezpieczeństwa musisz podać kod PIN"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Dla dodatkowego bezpieczeństwa musisz podać hasło"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Po przełączeniu profili wymagany jest wzór"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Po przełączeniu profili wymagany jest kod PIN"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Po przełączeniu profili wymagane jest hasło"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="few">Urządzenie nie zostało odblokowane od <xliff:g id="NUMBER_1">%d</xliff:g> godzin. Potwierdź wzór.</item>
       <item quantity="many">Urządzenie nie zostało odblokowane od <xliff:g id="NUMBER_1">%d</xliff:g> godzin. Potwierdź wzór.</item>
diff --git a/packages/Keyguard/res/values-pt-rBR/strings.xml b/packages/Keyguard/res/values-pt-rBR/strings.xml
index 19d1e4a..4f1afab 100644
--- a/packages/Keyguard/res/values-pt-rBR/strings.xml
+++ b/packages/Keyguard/res/values-pt-rBR/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sem serviço."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alterar botão do método de entrada."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modo avião"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"O padrão é exigido quando você reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"O PIN é exigido quando você reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"A senha é exigida quando você reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"O padrão é necessário para aumentar a segurança."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"O PIN é necessário para aumentar a segurança."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"A senha é necessária para aumentar a segurança."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"O padrão é exigido quando você troca de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"O PIN é exigido quando você troca de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"A senha é exigida quando você troca de perfil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"O padrão é exigido após a reinicialização do dispositivo"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"O PIN é exigido após a reinicialização do dispositivo"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"A senha é exigida após a reinicialização do dispositivo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"O padrão é necessário para aumentar a segurança"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"O PIN é necessário para aumentar a segurança"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"A senha é necessária para aumentar a segurança"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"O padrão é exigido quando você troca de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"O PIN é exigido quando você troca de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"A senha é exigida quando você troca de perfil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o padrão.</item>
       <item quantity="other">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o padrão.</item>
diff --git a/packages/Keyguard/res/values-pt-rPT/strings.xml b/packages/Keyguard/res/values-pt-rPT/strings.xml
index 5fda4d7..49c2f16 100644
--- a/packages/Keyguard/res/values-pt-rPT/strings.xml
+++ b/packages/Keyguard/res/values-pt-rPT/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sem serviço."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alternar botão de método de introdução."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modo de avião"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"É necessária a sequência quando reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"É necessário o PIN quando reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"É necessária a palavra-passe quando reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Para uma segurança adicional, é necessária uma sequência."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Para uma segurança adicional, é necessária um PIN."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Para uma segurança adicional, é necessária uma palavra-passe."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"É necessária a sequência quando muda de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"É necessário o PIN quando muda de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"É necessária a palavra-passe quando muda de perfil."</string>
+    <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 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>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme a sequência.</item>
       <item quantity="one">O dispositivo não é desbloqueado há <xliff:g id="NUMBER_0">%d</xliff:g> hora. Confirme a sequência.</item>
diff --git a/packages/Keyguard/res/values-pt/strings.xml b/packages/Keyguard/res/values-pt/strings.xml
index 19d1e4a..4f1afab 100644
--- a/packages/Keyguard/res/values-pt/strings.xml
+++ b/packages/Keyguard/res/values-pt/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sem serviço."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alterar botão do método de entrada."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modo avião"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"O padrão é exigido quando você reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"O PIN é exigido quando você reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"A senha é exigida quando você reinicia o dispositivo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"O padrão é necessário para aumentar a segurança."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"O PIN é necessário para aumentar a segurança."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"A senha é necessária para aumentar a segurança."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"O padrão é exigido quando você troca de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"O PIN é exigido quando você troca de perfil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"A senha é exigida quando você troca de perfil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"O padrão é exigido após a reinicialização do dispositivo"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"O PIN é exigido após a reinicialização do dispositivo"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"A senha é exigida após a reinicialização do dispositivo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"O padrão é necessário para aumentar a segurança"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"O PIN é necessário para aumentar a segurança"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"A senha é necessária para aumentar a segurança"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"O padrão é exigido quando você troca de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"O PIN é exigido quando você troca de perfil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"A senha é exigida quando você troca de perfil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o padrão.</item>
       <item quantity="other">O dispositivo não foi desbloqueado há <xliff:g id="NUMBER_1">%d</xliff:g> horas. Confirme o padrão.</item>
diff --git a/packages/Keyguard/res/values-ro/strings.xml b/packages/Keyguard/res/values-ro/strings.xml
index bded162..2b279ad 100644
--- a/packages/Keyguard/res/values-ro/strings.xml
+++ b/packages/Keyguard/res/values-ro/strings.xml
@@ -112,15 +112,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Fără serviciu."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Buton pentru comutarea metodei de introducere."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Mod Avion"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Când reporniți dispozitivul este necesar să introduceți modelul."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Când reporniți dispozitivul este necesar să introduceți codul PIN."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Când reporniți dispozitivul este necesar să introduceți parola."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Pentru securitate suplimentară este necesar un șablon."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Pentru securitate suplimentară este necesar un cod PIN."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Pentru securitate suplimentară este necesară o parolă."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Când comutați între profiluri este necesar să introduceți modelul."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Când comutați între profiluri este necesar să introduceți codul PIN."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Când comutați între profiluri este necesar să introduceți parola."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Modelul este necesar după repornirea dispozitivului"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Codul PIN este necesar după repornirea dispozitivului"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Parola este necesară după repornirea dispozitivului"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Modelul este necesar pentru securitate suplimentară"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Codul PIN este necesar pentru securitate suplimentară"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Parola este necesară pentru securitate suplimentară"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Modelul este necesar când comutați între profiluri"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Codul PIN este necesar când comutați între profiluri"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Parola este necesară când comutați între profiluri"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="few">Dispozitivul nu a fost deblocat de <xliff:g id="NUMBER_1">%d</xliff:g> ore. Confirmați modelul.</item>
       <item quantity="other">Dispozitivul nu a fost deblocat de <xliff:g id="NUMBER_1">%d</xliff:g> de ore. Confirmați modelul.</item>
diff --git a/packages/Keyguard/res/values-ru/strings.xml b/packages/Keyguard/res/values-ru/strings.xml
index 713f399..2f03166 100644
--- a/packages/Keyguard/res/values-ru/strings.xml
+++ b/packages/Keyguard/res/values-ru/strings.xml
@@ -114,15 +114,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="489430505491862444">"После перезапуска устройства нужно ввести графический ключ."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"После перезапуска устройства нужно ввести PIN-код."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"После перезапуска устройства нужно ввести пароль."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"В качестве дополнительной меры безопасности введите графический ключ."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"В качестве дополнительной меры безопасности введите PIN-код."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"В качестве дополнительной меры безопасности введите пароль."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"После смены аккаунта нужно ввести графический ключ."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"После смены аккаунта нужно ввести PIN-код."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"После смены аккаунта нужно ввести пароль."</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="one">Устройство не разблокировали <xliff:g id="NUMBER_1">%d</xliff:g> час. Введите графический ключ ещё раз.</item>
       <item quantity="few">Устройство не разблокировали <xliff:g id="NUMBER_1">%d</xliff:g> часа. Введите графический ключ ещё раз.</item>
diff --git a/packages/Keyguard/res/values-si-rLK/strings.xml b/packages/Keyguard/res/values-si-rLK/strings.xml
index 4ec025a..82ef914 100644
--- a/packages/Keyguard/res/values-si-rLK/strings.xml
+++ b/packages/Keyguard/res/values-si-rLK/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="489430505491862444">"ඔබ උපාංගය නැවත ආරම්භ කරන විට රටාව අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ඔබ උපාංගය නැවත ආරම්භ කරන විට PIN අංකය අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ඔබ උපාංගය නැවත ආරම්භ කරන විට මුරපදය අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"අමතර ආරක්ෂාව සඳහා රටාව අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"අමතර ආරක්ෂාව සඳහා PIN අංකය අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"අමතර ආරක්ෂාව සඳහා මුරපදය අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ඔබ පැතිකඩවල් මාරු කරන විට රටාව අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ඔබ පැතිකඩවල් මාරු කරන විට PIN අංකය අවශ්‍යයි."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ඔබ පැතිකඩවල් මාරු කරන විට මුරපදය අවශ්‍යයි."</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="one">උපාංගය පැය <xliff:g id="NUMBER_1">%d</xliff:g>කට අගුලු හැර නැත. රටාව තහවුරු කරන්න.</item>
       <item quantity="other">උපාංගය පැය <xliff:g id="NUMBER_1">%d</xliff:g>කට අගුලු හැර නැත. රටාව තහවුරු කරන්න.</item>
diff --git a/packages/Keyguard/res/values-sk/strings.xml b/packages/Keyguard/res/values-sk/strings.xml
index f9470ea..72958ce 100644
--- a/packages/Keyguard/res/values-sk/strings.xml
+++ b/packages/Keyguard/res/values-sk/strings.xml
@@ -114,15 +114,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Žiadny signál"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačidlo prepnutia metódy vstupu."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Režim v lietadle"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Pri reštartovaní zariadenia sa vyžaduje bezpečnostný vzor."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Pri reštartovaní zariadenia sa vyžaduje kód PIN."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Pri reštartovaní zariadenia sa vyžaduje heslo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Na ďalšie zabezpečenie sa vyžaduje vzor."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Na ďalšie zabezpečenie sa vyžaduje kód PIN."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Na ďalšie zabezpečenie sa vyžaduje heslo."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po prepnutí profilov sa vyžaduje bezpečnostný vzor."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po prepnutí profilov sa vyžaduje kód PIN."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po prepnutí profilov sa vyžaduje heslo."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Po reštartovaní zariadenia musíte zadať bezpečnostný vzor"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Po reštartovaní zariadenia musíte zadať kód PIN"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Po reštartovaní zariadenia musíte zadať heslo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Na ďalšie zabezpečenie musíte zadať bezpečnostný vzor"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Na ďalšie zabezpečenie musíte zadať kód PIN"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Na ďalšie zabezpečenie musíte zadať heslo"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Po prepnutí profilov musíte zadať bezpečnostný vzor"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Po prepnutí profilov musíte zadať kód PIN"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Po prepnutí profilov musíte zadať heslo"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="few">Zariadenie nebolo odomknuté <xliff:g id="NUMBER_1">%d</xliff:g> hodiny. Potvrďte vzor.</item>
       <item quantity="many">Zariadenie nebolo odomknuté <xliff:g id="NUMBER_1">%d</xliff:g> hodiny. Potvrďte vzor.</item>
diff --git a/packages/Keyguard/res/values-sl/strings.xml b/packages/Keyguard/res/values-sl/strings.xml
index 1807bd8..83a6e49 100644
--- a/packages/Keyguard/res/values-sl/strings.xml
+++ b/packages/Keyguard/res/values-sl/strings.xml
@@ -114,15 +114,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ni storitve."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Gumb za preklop načina vnosa."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Način za letalo"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Po vnovičnem zagonu je treba vnesti vzorec."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Po vnovičnem zagonu je treba vnesti kodo PIN."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Po vnovičnem zagonu je treba vnesti geslo."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Zaradi dodatne varnosti morate vnesti vzorec."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Zaradi dodatne varnosti morate vnesti kodo PIN."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Zaradi dodatne varnosti morate vnesti geslo."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Po preklopu profilov je treba vnesti vzorec."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Po preklopu profilov je treba vnesti kodo PIN."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Po preklopu profilov je treba vnesti geslo."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Po vnovičnem zagonu naprave je treba vnesti vzorec"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Po vnovičnem zagonu naprave je treba vnesti kodo PIN"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Po vnovičnem zagonu naprave je treba vnesti geslo"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Zaradi dodatne varnosti morate vnesti vzorec"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Zaradi dodatne varnosti morate vnesti kodo PIN"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Zaradi dodatne varnosti morate vnesti geslo"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Po preklopu profilov je treba vnesti vzorec"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Po preklopu profilov je treba vnesti kodo PIN"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Po preklopu profilov je treba vnesti geslo"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Naprava ni bila odklenjena <xliff:g id="NUMBER_1">%d</xliff:g> uro. Potrdite vzorec.</item>
       <item quantity="two">Naprava ni bila odklenjena <xliff:g id="NUMBER_1">%d</xliff:g> uri. Potrdite vzorec.</item>
diff --git a/packages/Keyguard/res/values-sq-rAL/strings.xml b/packages/Keyguard/res/values-sq-rAL/strings.xml
index 3b34db5..4cd2692 100644
--- a/packages/Keyguard/res/values-sq-rAL/strings.xml
+++ b/packages/Keyguard/res/values-sq-rAL/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nuk ka shërbim."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Butoni i metodës së ndërrimit të hyrjeve."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Modaliteti i aeroplanit"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Kërkohet motivi kur rinis pajisjen."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Kërkohet kodi PIN kur rinis pajisjen."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Kërkohet fjalëkalimi kur rinis pajisjen."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Kërkohet motivi për më shumë siguri."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Kërkohet kodi PIN për më shumë siguri."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Kërkohet fjalëkalimi për më shumë siguri."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Kërkohet motivi kur ndryshon profilet."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Kërkohet kodi PIN kur ndryshon profilet."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Kërkohet fjalëkalimi kur ndryshon profilet."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Kërkohet motivi pas rinisjes së pajisjes"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Kërkohet kodi PIN pas rinisjes së pajisjes"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Kërkohet fjalëkalimi pas rinisjes së pajisjes"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Kërkohet motivi për më shumë siguri"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Kërkohet kodi PIN për më shumë siguri"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Kërkohet fjalëkalimi për më shumë siguri"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Kërkohet motivi kur ndryshon profilet"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Kërkohet kodi PIN kur ndryshon profilet"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Kërkohet fjalëkalimi kur ndryshon profilet"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Pajisja nuk është shkyçur për <xliff:g id="NUMBER_1">%d</xliff:g> orë. Konfirmo motivin.</item>
       <item quantity="one">Pajisja nuk është shkyçur për <xliff:g id="NUMBER_0">%d</xliff:g> orë. Konfirmo motivin.</item>
diff --git a/packages/Keyguard/res/values-sr/strings.xml b/packages/Keyguard/res/values-sr/strings.xml
index 6e311e9..fa6bc09 100644
--- a/packages/Keyguard/res/values-sr/strings.xml
+++ b/packages/Keyguard/res/values-sr/strings.xml
@@ -112,15 +112,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="489430505491862444">"Шаблон је обавезан када поново покрећете уређај."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN је обавезан када поново покрећете уређај."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Лозинка је обавезна када поново покрећете уређај."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Потребан је шаблон ради додатне безбедности."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Потребан је PIN ради додатне безбедности."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Потребна је лозинка ради додатне безбедности."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Шаблон је обавезан када прелазите са једног профила на други."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN је обавезан када прелазите са једног профила на други."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Лозинка је обавезна када прелазите са једног профила на други."</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="one">Нисте откључали уређај <xliff:g id="NUMBER_1">%d</xliff:g> сат. Потврдите шаблон.</item>
       <item quantity="few">Нисте откључали уређај <xliff:g id="NUMBER_1">%d</xliff:g> сата. Потврдите шаблон.</item>
diff --git a/packages/Keyguard/res/values-sv/strings.xml b/packages/Keyguard/res/values-sv/strings.xml
index 19afea3..10b5991 100644
--- a/packages/Keyguard/res/values-sv/strings.xml
+++ b/packages/Keyguard/res/values-sv/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ingen tjänst."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knapp för byte av inmatningsmetod."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Flygplansläge"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Du måste ange grafiskt lösenord när du startar om enheten."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Du måste ange pinkod när du startar om enheten."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Du måste ange lösenord när du startar om enheten."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mönster krävs för ytterligare säkerhet."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Pinkod krävs för ytterligare säkerhet."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Lösenord krävs för ytterligare säkerhet."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Du måste ange grafiskt lösenord när du byter profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Du måste ange pinkod när du byter profil."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Du måste ange lösenord när du byter profil."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Du måste ange grafiskt lösenord när du startat om enheten"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Du måste ange pinkod när du startat om enheten"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Du måste ange lösenord när du startat om enheten"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Du måste ange grafiskt lösenord för ytterligare säkerhet"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Du måste ange pinkod för ytterligare säkerhet"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Du måste ange lösenord för ytterligare säkerhet"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Du måste ange grafiskt lösenord när du byter profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Du måste ange pinkod när du byter profil"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Du måste ange lösenord när du byter profil"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Enheten har inte låsts upp på <xliff:g id="NUMBER_1">%d</xliff:g> timmar. Bekräfta det grafiska lösenordet.</item>
       <item quantity="one">Enheten har inte låsts upp på <xliff:g id="NUMBER_0">%d</xliff:g> timme. Bekräfta det grafiska lösenordet.</item>
diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml
index 2f2c9d8..77eaf2a 100644
--- a/packages/Keyguard/res/values-sw/strings.xml
+++ b/packages/Keyguard/res/values-sw/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Hakuna huduma."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Swichi kitufe cha mbinu ingizi."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Hali ya ndegeni"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Mchoro unahitajika unapoanzisha kifaa upya."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"PIN inahitajika unapoanzisha kifaa upya."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Nenosiri linahitajika unapoanzisha kifaa upya."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Mchoro unatakikana ili kuongeza usalama."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"PIN inatakikana ili kuongeza usalama."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Nenosiri linahitajika ili kuongeza usalama."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Mchoro unahitajika unapobadili wasifu."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"PIN inahitajika unapobadili wasifu."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Nenosiri linahitajika unapobadili wasifu."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Mchoro unahitajika baada ya kuanzisha kifaa upya"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN inahitajika baada ya kifaa kuanzishwa upya"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Nenosiri linahitajika baada ya kuanzisha kifaa upya"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Mchoro unatakikana ili kuongeza usalama"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"PIN inatakikana ili kuongeza usalama"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Nenosiri linatakikana ili kuongeza usalama"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Mchoro unahitajika unapobadili wasifu"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"PIN inahitajika unapobadili wasifu"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Nenosiri linahitajika unapobadili wasifu"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Kifaa hakijafunguliwa kwa saa <xliff:g id="NUMBER_1">%d</xliff:g>. Thibitisha mchoro.</item>
       <item quantity="one">Kifaa hakijafunguliwa kwa saa <xliff:g id="NUMBER_0">%d</xliff:g>. Thibitisha mchoro.</item>
diff --git a/packages/Keyguard/res/values-ta-rIN/strings.xml b/packages/Keyguard/res/values-ta-rIN/strings.xml
index 869c867..5ddad8c 100644
--- a/packages/Keyguard/res/values-ta-rIN/strings.xml
+++ b/packages/Keyguard/res/values-ta-rIN/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="489430505491862444">"சாதனத்தை மீண்டும் தொடங்கும் போது, வடிவம் தேவை."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"சாதனத்தை மீண்டும் தொடங்கும் போது, பின் தேவை."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"சாதனத்தை மீண்டும் தொடங்கும் போது, கடவுச்சொல் தேவை."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"கூடுதல் பாதுகாப்பிற்கு வடிவம் தேவை."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"கூடுதல் பாதுகாப்பிற்கு PIN தேவை."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"கூடுதல் பாதுகாப்பிற்குக் கடவுச்சொல் தேவை."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"சுயவிவரங்களுக்கு இடையே மாறும் போது, வடிவம் தேவை."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"சுயவிவரங்களுக்கு இடையே மாறும் போது, பின் தேவை."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"சுயவிவரங்களுக்கு இடையே மாறும் போது, கடவுச்சொல் தேவை."</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>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"சுயவிவரங்களுக்கு இடையே மாறும் போது, வடிவத்தை வரைய வேண்டும்"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"சுயவிவரங்களுக்கு இடையே மாறும் போது, பின்னை உள்ளிட வேண்டும்"</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>
diff --git a/packages/Keyguard/res/values-te-rIN/strings.xml b/packages/Keyguard/res/values-te-rIN/strings.xml
index 6513648..e10490c 100644
--- a/packages/Keyguard/res/values-te-rIN/strings.xml
+++ b/packages/Keyguard/res/values-te-rIN/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="489430505491862444">"మీరు పరికరాన్ని పునఃప్రారంభించినప్పుడు నమూనా అవసరం."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"మీరు పరికరాన్ని పునఃప్రారంభించినప్పుడు PIN అవసరం."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"మీరు పరికరాన్ని పునఃప్రారంభించినప్పుడు పాస్‌వర్డ్ అవసరం."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"అదనపు భద్రత కోసం నమూనా అవసరం."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"అదనపు భద్రత కోసం PIN అవసరం."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"అదనపు భద్రత కోసం పాస్‌వర్డ్ అవసరం."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"మీరు ప్రొఫైల్‌లను మార్చినప్పుడు నమూనా అవసరం."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"మీరు ప్రొఫైల్‌లను మార్చినప్పుడు PIN అవసరం."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"మీరు ప్రొఫైల్‌లను మార్చినప్పుడు పాస్‌వర్డ్ అవసరం."</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> గంటల పాటు అన్‌లాక్ చేయబడలేదు. నమూనాను నిర్ధారించండి.</item>
       <item quantity="one">పరికరం <xliff:g id="NUMBER_0">%d</xliff:g> గంట పాటు అన్‌లాక్ చేయబడలేదు. నమూనాను నిర్ధారించండి.</item>
diff --git a/packages/Keyguard/res/values-th/strings.xml b/packages/Keyguard/res/values-th/strings.xml
index 71d108c..d3fe71e 100644
--- a/packages/Keyguard/res/values-th/strings.xml
+++ b/packages/Keyguard/res/values-th/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="489430505491862444">"ต้องใช้รูปแบบเมื่อคุณรีสตาร์ทอุปกรณ์"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"ต้องใช้ PIN เมื่อคุณรีสตาร์ทอุปกรณ์"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"ต้องใช้รหัสผ่านเมื่อคุณรีสตาร์ทอุปกรณ์"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"ต้องใช้รูปแบบเพื่อความปลอดภัยเพิ่มเติม"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"ต้องใช้ PIN เพื่อความปลอดภัยเพิ่มเติม"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"ต้องใช้รหัสผ่านเพื่อความปลอดภัยเพิ่มเติม"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"ต้องใช้รูปแบบเมื่อคุณเปลี่ยนโปรไฟล์"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"ต้องใช้ PIN เมื่อคุณเปลี่ยนโปรไฟล์"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"ต้องใช้รหัสผ่านเมื่อคุณเปลี่ยนโปรไฟล์"</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> ชั่วโมง ยืนยันรูปแบบ</item>
       <item quantity="one">ไม่มีการปลดล็อกอุปกรณ์เป็นเวลา <xliff:g id="NUMBER_0">%d</xliff:g> ชั่วโมง ยืนยันรูปแบบ </item>
diff --git a/packages/Keyguard/res/values-tl/strings.xml b/packages/Keyguard/res/values-tl/strings.xml
index 433fdbf..6e6adec 100644
--- a/packages/Keyguard/res/values-tl/strings.xml
+++ b/packages/Keyguard/res/values-tl/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Walang serbisyo."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ilipat ang button na pamamaraan ng pag-input."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Airplane mode"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Kinakailangan ang pattern kapag ni-restart mo ang device."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Kinakailangan ang PIN kapag ni-restart mo ang device."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Kinakailangan ang password kapag ni-restart mo ang device."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Kinakailangan ang pattern para sa karagdagang seguridad."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Kinakailangan ang PIN para sa karagdagang seguridad."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Kinakailangan ang password para sa karagdagang seguridad."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Kinakailangan ang pattern kapag lumipat ka ng mga profile."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Kinakailangan ang PIN kapag lumipat ka ng mga profile."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Kinakailangan ang password kapag lumipat ka ng mga profile."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Kinakailangan ang pattern pagkatapos mag-restart ng device"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Kinakailangan ang PIN pagkatapos mag-restart ng device"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Kinakailangan ang password pagkatapos mag-restart ng device"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Kinakailangan ang pattern para sa karagdagang seguridad"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Kinakailangan ang PIN para sa karagdagang seguridad"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Kinakailangan ang password para sa karagdagang seguridad"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Kinakailangan ang pattern kapag nagpalit ka ng profile"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Kinakailangan ang PIN kapag nagpalit ka ng profile"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Kinakailangan ang password kapag nagpalit ka ng profile"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Hindi na-unlock ang device sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> oras.. Kumpirmahin ang pattern.</item>
       <item quantity="other">Hindi na-unlock ang device sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> na oras. Kumpirmahin ang pattern.</item>
diff --git a/packages/Keyguard/res/values-tr/strings.xml b/packages/Keyguard/res/values-tr/strings.xml
index c9649d5..46c3d00 100644
--- a/packages/Keyguard/res/values-tr/strings.xml
+++ b/packages/Keyguard/res/values-tr/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Hizmet yok."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Giriş yöntemini değiştirme düğmesi."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Uçak modu"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Cihazı yeniden başlattığınızda desen gerekir."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Cihazı yeniden başlattığınızda PIN gerekir."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Cihazı yeniden başlattığınızda şifre gerekir."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Ek güvenlik için desen gerekiyor."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Ek güvenlik için PIN gerekiyor."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Ek güvenlik için şifre gerekiyor."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profil değiştirdiğinizde desen gerekir."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profil değiştirdiğinizde PIN gerekir."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profil değiştirdiğinizde şifre gerekir."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Cihaz yeniden başladıktan sonra desen gerekir"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Cihaz yeniden başladıktan sonra PIN gerekir"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Cihaz yeniden başladıktan sonra şifre gerekir"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Ek güvenlik için desen gerekir"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Ek güvenlik için PIN gerekir"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Ek güvenlik için şifre gerekir"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Profil değiştirdiğinizde desen gerekir"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Profil değiştirdiğinizde PIN gerekir"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Profil değiştirdiğinizde şifre gerekir"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Cihazın kilidi son <xliff:g id="NUMBER_1">%d</xliff:g> saattir açılmadı. Deseni doğrulayın.</item>
       <item quantity="one">Cihazın kilidi son <xliff:g id="NUMBER_0">%d</xliff:g> saattir açılmadı. Deseni doğrulayın.</item>
diff --git a/packages/Keyguard/res/values-uk/strings.xml b/packages/Keyguard/res/values-uk/strings.xml
index e4b0e1f..c1b742e 100644
--- a/packages/Keyguard/res/values-uk/strings.xml
+++ b/packages/Keyguard/res/values-uk/strings.xml
@@ -114,15 +114,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="489430505491862444">"Після перезавантаження пристрою потрібно ввести ключ."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Після перезавантаження пристрою потрібно ввести PIN-код."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Після перезавантаження пристрою потрібно ввести пароль."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Введіть ключ. Це потрібно зробити з міркувань безпеки."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Введіть PIN-код. Це потрібно зробити з міркувань безпеки."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Введіть пароль. Це потрібно зробити з міркувань безпеки."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Після переходу в інший профіль потрібно ввести ключ."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Після переходу в інший профіль потрібно ввести PIN-код."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Після переходу в інший профіль потрібно ввести пароль."</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="one">Ви не розблоковували пристрій <xliff:g id="NUMBER_1">%d</xliff:g> годину. Підтвердьте ключ.</item>
       <item quantity="few">Ви не розблоковували пристрій <xliff:g id="NUMBER_1">%d</xliff:g> години. Підтвердьте ключ.</item>
diff --git a/packages/Keyguard/res/values-ur-rPK/strings.xml b/packages/Keyguard/res/values-ur-rPK/strings.xml
index 3a041f5..48986e6 100644
--- a/packages/Keyguard/res/values-ur-rPK/strings.xml
+++ b/packages/Keyguard/res/values-ur-rPK/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="489430505491862444">"جب آپ آلہ کو دوبارہ شروع کرتے ہیں تو پیٹرن درکار ہوتا ہے۔"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"‏جب آپ آلہ کو دوبارہ شروع کرتے ہیں تو PIN درکار ہوتا ہے۔"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"جب آپ آلہ کو دوبارہ شروع کرتے ہیں تو پاسورڈ درکار ہوتا ہے۔"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"اضافی سیکیورٹی کیلئے پیٹرن درکار ہے۔"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"‏اضافی سیکیورٹی کیلئے PIN درکار ہے۔"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"اضافی سیکیورٹی کیلئے پاسورڈ درکار ہے۔"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"جب آپ پروفائل سوئچ کرتے ہیں تو پیٹرن درکار ہوتا ہے۔"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"‏جب آپ پروفائل سوئچ کرتے ہیں تو PIN درکار ہوتا ہے۔"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"جب آپ پروفائل سوئچ کرتے ہیں تو پاسورڈ درکار ہوتا ہے۔"</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> گھنٹے سے غیر مقفل نہیں کیا گیا۔ پیٹرن کی تصدیق کریں۔</item>
       <item quantity="one">آلہ <xliff:g id="NUMBER_0">%d</xliff:g> گھنٹے سے غیر مقفل نہیں کیا گیا۔ پیٹرن کی تصدیق کریں۔</item>
diff --git a/packages/Keyguard/res/values-uz-rUZ/strings.xml b/packages/Keyguard/res/values-uz-rUZ/strings.xml
index 44d5b50..7e9f504 100644
--- a/packages/Keyguard/res/values-uz-rUZ/strings.xml
+++ b/packages/Keyguard/res/values-uz-rUZ/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Aloqa yo‘q."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Kiritish uslubi tugmasini almashtirish."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Parvoz rejimi"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Qurilmani o‘chirib yoqishda chizmali kalit talab qilinadi."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Qurilmani o‘chirib yoqishda PIN-kod talab qilinadi."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Qurilmani o‘chirib yoqishda parol talab qilinadi."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Qo‘shimcha xavfsizlik chorasi sifatida chizmali kalit talab qilinadi."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Qo‘shimcha xavfsizlik chorasi sifatida PIN-kod talab qilinadi."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Qo‘shimcha xavfsizlik chorasi sifatida parol talab qilinadi."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Profilni amlashtirishda chizmali kalit talab qilinadi."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Profilni amlashtirishda PIN-kod talab qilinadi."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Profilni amlashtirishda parol talab qilinadi."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Qurilma o‘chirib yoqilgandan so‘ng chizmali kalit talab qilinadi"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Qurilma o‘chirib yoqilgandan so‘ng PIN kod talab qilinadi"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Qurilma o‘chirib yoqilgandan so‘ng parol talab qilinadi"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Qo‘shimcha xavfsizlik chorasi sifatida chizmali kalit talab qilinadi"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Qo‘shimcha xavfsizlik chorasi sifatida PIN kod talab qilinadi"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Qo‘shimcha xavfsizlik chorasi sifatida parol talab qilinadi"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Profilni amlashtirishda chizmali kalit talab qilinadi"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Profilni amlashtirishda PIN kod talab qilinadi"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Profilni amlashtirishda parol talab qilinadi"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Qurilma <xliff:g id="NUMBER_1">%d</xliff:g> soatdan beri qulfdan chiqarilgani yo‘q. Chizmali kalitni yana bir marta kiriting.</item>
       <item quantity="one">Qurilma <xliff:g id="NUMBER_0">%d</xliff:g> soatdan beri qulfdan chiqarilgani yo‘q. Chizmali kalitni yana bir marta kiriting.</item>
diff --git a/packages/Keyguard/res/values-vi/strings.xml b/packages/Keyguard/res/values-vi/strings.xml
index 8d72cd1..6f81101 100644
--- a/packages/Keyguard/res/values-vi/strings.xml
+++ b/packages/Keyguard/res/values-vi/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Không có dịch vụ."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Nút chuyển phương thức nhập."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Chế độ trên máy bay"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Yêu cầu hình khi bạn khởi động lại thiết bị."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Yêu cầu mã PIN khi bạn khởi động lại thiết bị."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Yêu cầu mật khẩu khi bạn khởi động lại thiết bị."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Cần có mẫu hình để bảo mật thêm."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Cần có mã PIN để bảo mật thêm."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Cần có mật khẩu để bảo mật thêm."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Yêu cầu hình khi bạn chuyển đổi hồ sơ."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Yêu cầu mã PIN khi bạn chuyển đổi hồ sơ."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Yêu cầu mật khẩu khi bạn chuyển đổi hồ sơ."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Yêu cầu hình mở khóa sau khi thiết bị khởi động lại"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Yêu cầu mã PIN sau khi thiết bị khởi động lại"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Yêu cầu mật khẩu sau khi thiết bị khởi động lại"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Cần có hình mở khóa để bảo mật thêm"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Cần có mã PIN để bảo mật thêm"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Cần có mật khẩu để bảo mật thêm"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Yêu cầu hình mở khóa khi bạn chuyển đổi hồ sơ"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Yêu cầu mã PIN khi bạn chuyển đổi hồ sơ"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Yêu cầu mật khẩu khi bạn chuyển đổi hồ sơ"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Thiết bị đã không được mở khóa trong <xliff:g id="NUMBER_1">%d</xliff:g> giờ. Xác nhận hình.</item>
       <item quantity="one">Thiết bị đã không được mở khóa trong <xliff:g id="NUMBER_0">%d</xliff:g> giờ. Xác nhận hình.</item>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index dc017fb..2c86a7a 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/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="489430505491862444">"重启设备后需要绘制图案。"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"重启设备后需要输入 PIN 码。"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"重启设备后需要输入密码。"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"需要绘制解锁图案,以进一步确保安全。"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"需要输入 PIN 码,以进一步确保安全。"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"需要输入密码,以进一步确保安全。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"切换资料后需要绘制图案。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"切换资料后需要输入 PIN 码。"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"切换资料后需要输入密码。"</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> 小时。请确认解锁图案。</item>
       <item quantity="one">设备已保持锁定状态达 <xliff:g id="NUMBER_0">%d</xliff:g> 小时。请确认解锁图案。</item>
diff --git a/packages/Keyguard/res/values-zh-rHK/strings.xml b/packages/Keyguard/res/values-zh-rHK/strings.xml
index 82802d4..f21dbca 100644
--- a/packages/Keyguard/res/values-zh-rHK/strings.xml
+++ b/packages/Keyguard/res/values-zh-rHK/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="489430505491862444">"需要圖案方可重新啟動裝置。"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"需要 PIN 方可重新啟動裝置。"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"需要密碼方可重新啟動裝置。"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"需要使用圖案以提高安全性。"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"需要使用 PIN 以提高安全性。"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"需要使用密碼以提高安全性。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"需要圖案方可切換設定檔。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"需要 PIN 方可切換設定檔。"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"需要密碼方可切換設定檔。"</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> 小時後尚未解鎖,請確認圖案。</item>
       <item quantity="one">裝置在 <xliff:g id="NUMBER_0">%d</xliff:g> 小時後尚未解鎖,請確認圖案。</item>
diff --git a/packages/Keyguard/res/values-zh-rTW/strings.xml b/packages/Keyguard/res/values-zh-rTW/strings.xml
index 800d0a0..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="489430505491862444">"重新啟動裝置時需要確認圖形。"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"重新啟動裝置時需要確認 PIN 碼。"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"重新啟動裝置時需要確認密碼。"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"請輸入解鎖圖形,以進一步確保資訊安全。"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"請輸入 PIN 碼,以進一步確保資訊安全。"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"請輸入密碼,以進一步確保資訊安全。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"切換設定檔時需要確認圖形。"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"切換設定檔時需要確認 PIN 碼。"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"切換設定檔時需要確認密碼。"</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> 小時未解鎖。請確認圖形。</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/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
index e1a54d1..9e17dba 100644
--- a/packages/Keyguard/res/values-zu/strings.xml
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ayikho isevisi."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Vula indlela yokungena yenkinobho"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Isimo sendiza"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="489430505491862444">"Iphethini iyadingeka uma uqalisa kabusha idivayisi."</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="994878216570694974">"Iphinikhodi iyadingeka uma uqalisa kabusha idivayisi."</string>
-    <string name="kg_prompt_reason_restart_password" msgid="2375742919528461664">"Iphasiwedi iyadingeka uma uqalisa kabusha idivayisi."</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="8930047492617900785">"Iphethini iyadingeka ngokuvikela okungeziwe."</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="7470468607947726377">"Iphinikhodi iyadingeka ngokuvikela okungeziwe."</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="1177412542773936957">"Iphasiwedi iyadingeka ngokuvikela okungeziwe."</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3802056699323773969">"Iphethini iyadingeka uma ushintsha amaphrofayela."</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="8108020184731052246">"Iphinikhodi iyadingeka uma ushintsha amaphrofayela."</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="6755997057852042672">"Iphasiwedi iyadingeka uma ushintsha amaphrofayela."</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Iphethini iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Iphinikhodi iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Iphasiwedi iyadingeka ngemuva kokuqala kabusha kwedivayisi"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Kudingeka iphethini  ngokuvikeleka okungeziwe"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Kudingeka iphinikhodi ngokuvikeleka okungeziwe"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Iphasiwedi idingelwa ukuvikela okungeziwe"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Iphethini iyadingeka uma ushintsha amaphrofayela"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Kudingeka iphinikhodi uma ushintsha amaphrofayela"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Iphasiwedi iyadingeka uma ushintsha amaphrofayela"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="one">Idivayisi ayikavulwa ngamahora angu-<xliff:g id="NUMBER_1">%d</xliff:g>. Qinisekisa iphethini.</item>
       <item quantity="other">Idivayisi ayikavulwa ngamahora angu-<xliff:g id="NUMBER_1">%d</xliff:g>. Qinisekisa iphethini.</item>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index dea5fa0..746457f 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -308,31 +308,31 @@
     <string name="airplane_mode">Airplane mode</string>
 
     <!-- An explanation text that the pattern needs to be solved since the device has just been restarted. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_restart_pattern">Pattern required when you restart device.</string>
+    <string name="kg_prompt_reason_restart_pattern">Pattern required after device restarts</string>
 
     <!-- An explanation text that the pin needs to be entered since the device has just been restarted. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_restart_pin">PIN required when you restart device.</string>
+    <string name="kg_prompt_reason_restart_pin">PIN required after device restarts</string>
 
     <!-- An explanation text that the password needs to be entered since the device has just been restarted. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_restart_password">Password required when you restart device.</string>
+    <string name="kg_prompt_reason_restart_password">Password required after device restarts</string>
 
     <!-- An explanation text that the pattern needs to be solved since the user hasn't used strong authentication since quite some time. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_timeout_pattern">Pattern required for additional security.</string>
+    <string name="kg_prompt_reason_timeout_pattern">Pattern required for additional security</string>
 
     <!-- An explanation text that the pin needs to be entered since the user hasn't used strong authentication since quite some time. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_timeout_pin">PIN required for additional security.</string>
+    <string name="kg_prompt_reason_timeout_pin">PIN required for additional security</string>
 
     <!-- An explanation text that the password needs to be entered since the user hasn't used strong authentication since quite some time. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_timeout_password">Password required for additional security.</string>
+    <string name="kg_prompt_reason_timeout_password">Password required for additional security</string>
 
     <!-- An explanation text that the pattern needs to be solved since profiles have just been switched. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_switch_profiles_pattern">Pattern required when you switch profiles.</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern">Pattern required when you switch profiles</string>
 
     <!-- An explanation text that the pin needs to be entered since profiles have just been switched. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_switch_profiles_pin">PIN required when you switch profiles.</string>
+    <string name="kg_prompt_reason_switch_profiles_pin">PIN required when you switch profiles</string>
 
     <!-- An explanation text that the password needs to be entered since profiles have just been switched. [CHAR LIMIT=80] -->
-    <string name="kg_prompt_reason_switch_profiles_password">Password required when you switch profiles.</string>
+    <string name="kg_prompt_reason_switch_profiles_password">Password required when you switch profiles</string>
 
     <!-- An explanation text that the pattern needs to be solved since it hasn't been solved in a while. [CHAR LIMIT=80]-->
     <plurals name="kg_prompt_reason_time_pattern">
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index b03871a..64b443b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -123,39 +123,45 @@
             mPendingLockCheck.cancel(false);
         }
 
+        final int userId = KeyguardUpdateMonitor.getCurrentUser();
         if (entry.length() <= MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) {
             // to avoid accidental lockout, only count attempts that are long enough to be a
             // real password. This may require some tweaking.
             setPasswordEntryInputEnabled(true);
-            onPasswordChecked(false /* matched */, 0, false /* not valid - too short */);
+            onPasswordChecked(userId, false /* matched */, 0, false /* not valid - too short */);
             return;
         }
 
         mPendingLockCheck = LockPatternChecker.checkPassword(
                 mLockPatternUtils,
                 entry,
-                KeyguardUpdateMonitor.getCurrentUser(),
+                userId,
                 new LockPatternChecker.OnCheckCallback() {
                     @Override
                     public void onChecked(boolean matched, int timeoutMs) {
                         setPasswordEntryInputEnabled(true);
                         mPendingLockCheck = null;
-                        onPasswordChecked(matched, timeoutMs, true /* isValidPassword */);
+                        onPasswordChecked(userId, matched, timeoutMs,
+                                true /* isValidPassword */);
                     }
                 });
     }
 
-    private void onPasswordChecked(boolean matched, int timeoutMs, boolean isValidPassword) {
+    private void onPasswordChecked(int userId, boolean matched, int timeoutMs,
+            boolean isValidPassword) {
+        boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
         if (matched) {
-            mDismissing = true;
-            mCallback.reportUnlockAttempt(true, 0);
-            mCallback.dismiss(true);
+            mCallback.reportUnlockAttempt(userId, true, 0);
+            if (dismissKeyguard) {
+                mDismissing = true;
+                mCallback.dismiss(true);
+            }
         } else {
             if (isValidPassword) {
-                mCallback.reportUnlockAttempt(false, timeoutMs);
+                mCallback.reportUnlockAttempt(userId, false, timeoutMs);
                 if (timeoutMs > 0) {
                     long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
-                            KeyguardUpdateMonitor.getCurrentUser(), timeoutMs);
+                            userId, timeoutMs);
                     handleAttemptLockout(deadline);
                 }
             }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 29b319f..2a2f5a0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -227,22 +227,23 @@
                 mPendingLockCheck.cancel(false);
             }
 
+            final int userId = KeyguardUpdateMonitor.getCurrentUser();
             if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
                 mLockPatternView.enableInput();
-                onPatternChecked(false, 0, false /* not valid - too short */);
+                onPatternChecked(userId, false, 0, false /* not valid - too short */);
                 return;
             }
 
             mPendingLockCheck = LockPatternChecker.checkPattern(
                     mLockPatternUtils,
                     pattern,
-                    KeyguardUpdateMonitor.getCurrentUser(),
+                    userId,
                     new LockPatternChecker.OnCheckCallback() {
                         @Override
                         public void onChecked(boolean matched, int timeoutMs) {
                             mLockPatternView.enableInput();
                             mPendingLockCheck = null;
-                            onPatternChecked(matched, timeoutMs, true);
+                            onPatternChecked(userId, matched, timeoutMs, true);
                         }
                     });
             if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
@@ -250,18 +251,22 @@
             }
         }
 
-        private void onPatternChecked(boolean matched, int timeoutMs, boolean isValidPattern) {
+        private void onPatternChecked(int userId, boolean matched, int timeoutMs,
+                boolean isValidPattern) {
+            boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
             if (matched) {
-                mCallback.reportUnlockAttempt(true, 0);
-                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
-                mCallback.dismiss(true);
+                mCallback.reportUnlockAttempt(userId, true, 0);
+                if (dismissKeyguard) {
+                    mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
+                    mCallback.dismiss(true);
+                }
             } else {
                 mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
                 if (isValidPattern) {
-                    mCallback.reportUnlockAttempt(false, timeoutMs);
+                    mCallback.reportUnlockAttempt(userId, false, timeoutMs);
                     if (timeoutMs > 0) {
                         long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
-                                KeyguardUpdateMonitor.getCurrentUser(), timeoutMs);
+                                userId, timeoutMs);
                         handleAttemptLockout(deadline);
                     }
                 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
index 836c195..232d4d2 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -36,11 +36,12 @@
 
     /**
      * Call to report an unlock attempt.
+     * @param userId id of the user whose unlock attempt is recorded.
      * @param success set to 'true' if user correctly entered security credentials.
      * @param timeoutMs timeout in milliseconds to wait before reattempting an unlock.
      *                  Only nonzero if 'success' is false
      */
-    void reportUnlockAttempt(boolean success, int timeoutMs);
+    void reportUnlockAttempt(int userId, boolean success, int timeoutMs);
 
     /**
      * Resets the keyguard view.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index f45b9bd..409f6a7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -205,7 +205,8 @@
 
         if (messageId != 0) {
             final String message = mContext.getString(messageId,
-                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
+                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(
+                            KeyguardUpdateMonitor.getCurrentUser()),
                     timeoutInSeconds);
             showDialog(null, message);
         }
@@ -249,16 +250,15 @@
         showDialog(null, message);
     }
 
-    private void reportFailedUnlockAttempt(int timeoutMs) {
+    private void reportFailedUnlockAttempt(int userId, int timeoutMs) {
         final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
-        final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
+        final int failedAttempts = monitor.getFailedUnlockAttempts(userId) + 1; // +1 for this time
 
         if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
 
-        final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
         final DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
         final int failedAttemptsBeforeWipe =
-                dpm.getMaximumFailedPasswordsForWipe(null, currentUser);
+                dpm.getMaximumFailedPasswordsForWipe(null, userId);
 
         final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
                 (failedAttemptsBeforeWipe - failedAttempts)
@@ -268,9 +268,9 @@
             // N attempts. Once we get below the grace period, we post this dialog every time as a
             // clear warning until the deletion fires.
             // Check which profile has the strictest policy for failed password attempts
-            final int expiringUser = dpm.getProfileWithMinimumFailedPasswordsForWipe(currentUser);
+            final int expiringUser = dpm.getProfileWithMinimumFailedPasswordsForWipe(userId);
             int userType = USER_TYPE_PRIMARY;
-            if (expiringUser == currentUser) {
+            if (expiringUser == userId) {
                 // TODO: http://b/23522538
                 if (expiringUser != UserHandle.USER_SYSTEM) {
                     userType = USER_TYPE_SECONDARY_USER;
@@ -286,8 +286,8 @@
                 showWipeDialog(failedAttempts, userType);
             }
         }
-        monitor.reportFailedStrongAuthUnlockAttempt();
-        mLockPatternUtils.reportFailedPasswordAttempt(KeyguardUpdateMonitor.getCurrentUser());
+        monitor.reportFailedStrongAuthUnlockAttempt(userId);
+        mLockPatternUtils.reportFailedPasswordAttempt(userId);
         if (timeoutMs > 0) {
             showTimeoutDialog(timeoutMs);
         }
@@ -422,14 +422,13 @@
             return mIsVerifyUnlockOnly;
         }
 
-        public void reportUnlockAttempt(boolean success, int timeoutMs) {
+        public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) {
             KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
             if (success) {
                 monitor.clearFailedUnlockAttempts();
-                mLockPatternUtils.reportSuccessfulPasswordAttempt(
-                        KeyguardUpdateMonitor.getCurrentUser());
+                mLockPatternUtils.reportSuccessfulPasswordAttempt(userId);
             } else {
-                KeyguardSecurityContainer.this.reportFailedUnlockAttempt(timeoutMs);
+                KeyguardSecurityContainer.this.reportFailedUnlockAttempt(userId, timeoutMs);
             }
         }
 
@@ -445,7 +444,7 @@
         @Override
         public void userActivity() { }
         @Override
-        public void reportUnlockAttempt(boolean success, int timeoutMs) { }
+        public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) { }
         @Override
         public boolean isVerifyUnlockOnly() { return false; }
         @Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 8102c34..b4f9b9f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1552,12 +1552,12 @@
         mFailedAttempts.delete(sCurrentUser);
     }
 
-    public int getFailedUnlockAttempts() {
-        return mFailedAttempts.get(sCurrentUser, 0);
+    public int getFailedUnlockAttempts(int userId) {
+        return mFailedAttempts.get(userId, 0);
     }
 
-    public void reportFailedStrongAuthUnlockAttempt() {
-        mFailedAttempts.put(sCurrentUser, getFailedUnlockAttempts() + 1);
+    public void reportFailedStrongAuthUnlockAttempt(int userId) {
+        mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
     }
 
     public void clearFingerprintRecognized() {
diff --git a/packages/MtpDocumentsProvider/Android.mk b/packages/MtpDocumentsProvider/Android.mk
index 67bbf78..b31b0b1 100644
--- a/packages/MtpDocumentsProvider/Android.mk
+++ b/packages/MtpDocumentsProvider/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_CERTIFICATE := media
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_JNI_SHARED_LIBRARIES := libappfuse_jni
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
 include $(BUILD_PACKAGE)
 include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
index f9fb85c..66a3247 100644
--- a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
+++ b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
@@ -31,30 +31,37 @@
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "nativehelper/ScopedPrimitiveArray.h"
+#include "nativehelper/ScopedLocalRef.h"
 
 namespace {
 
-// Maximum number of bytes to write in one request.
+// The numbers came from sdcard.c.
+// Maximum number of bytes to write/read in one request/one reply.
 constexpr size_t MAX_WRITE = 256 * 1024;
+constexpr size_t MAX_READ = 128 * 1024;
+
 constexpr size_t NUM_MAX_HANDLES = 1024;
 
 // Largest possible request.
 // The request size is bounded by the maximum size of a FUSE_WRITE request
 // because it has the largest possible data payload.
 constexpr size_t MAX_REQUEST_SIZE = sizeof(struct fuse_in_header) +
-        sizeof(struct fuse_write_in) + MAX_WRITE;
+        sizeof(struct fuse_write_in) + (MAX_WRITE > MAX_READ ? MAX_WRITE : MAX_READ);
 
 static jclass app_fuse_class;
 static jmethodID app_fuse_get_file_size;
 static jmethodID app_fuse_get_object_bytes;
 
+// NOTE:
+// FuseRequest and FuseResponse shares the same buffer to save memory usage, so the handlers must
+// not access input buffer after writing data to output buffer.
 struct FuseRequest {
     char buffer[MAX_REQUEST_SIZE];
     FuseRequest() {}
     const struct fuse_in_header& header() const {
         return *(const struct fuse_in_header*) buffer;
     }
-    const void* data() const {
+    void* data() {
         return (buffer + sizeof(struct fuse_in_header));
     }
     size_t data_length() const {
@@ -62,6 +69,26 @@
     }
 };
 
+template<typename T>
+class FuseResponse {
+   size_t size_;
+   T* const buffer_;
+public:
+   FuseResponse(void* buffer) : size_(0), buffer_(static_cast<T*>(buffer)) {}
+
+   void prepare_buffer(size_t size = sizeof(T)) {
+       memset(buffer_, 0, size);
+       size_ = size;
+   }
+
+   void set_size(size_t size) {
+       size_ = size;
+   }
+
+   size_t size() const { return size_; }
+   T* data() const { return buffer_; }
+};
+
 class ScopedFd {
     int mFd;
 
@@ -76,7 +103,7 @@
 };
 
 /**
- * The class is used to access AppFuse class in Java from fuse handlers.
+ * Fuse implementation consists of handlers parsing FUSE commands.
  */
 class AppFuse {
     JNIEnv* env_;
@@ -90,9 +117,9 @@
     AppFuse(JNIEnv* env, jobject self) :
         env_(env), self_(self), handle_counter_(0) {}
 
-    bool handle_fuse_request(int fd, const FuseRequest& req) {
-        ALOGV("Request op=%d", req.header().opcode);
-        switch (req.header().opcode) {
+    bool handle_fuse_request(int fd, FuseRequest* req) {
+        ALOGV("Request op=%d", req->header().opcode);
+        switch (req->header().opcode) {
             // TODO: Handle more operations that are enough to provide seekable
             // FD.
             case FUSE_LOOKUP:
@@ -110,20 +137,20 @@
                 invoke_handler(fd, req, &AppFuse::handle_fuse_open);
                 return true;
             case FUSE_READ:
-                invoke_handler(fd, req, &AppFuse::handle_fuse_read, 8192);
+                invoke_handler(fd, req, &AppFuse::handle_fuse_read);
                 return true;
             case FUSE_RELEASE:
-                invoke_handler(fd, req, &AppFuse::handle_fuse_release, 0);
+                invoke_handler(fd, req, &AppFuse::handle_fuse_release);
                 return true;
             case FUSE_FLUSH:
-                invoke_handler(fd, req, &AppFuse::handle_fuse_flush, 0);
+                invoke_handler(fd, req, &AppFuse::handle_fuse_flush);
                 return true;
             default: {
                 ALOGV("NOTIMPL op=%d uniq=%" PRIx64 " nid=%" PRIx64 "\n",
-                      req.header().opcode,
-                      req.header().unique,
-                      req.header().nodeid);
-                fuse_reply(fd, req.header().unique, -ENOSYS, NULL, 0);
+                      req->header().opcode,
+                      req->header().unique,
+                      req->header().nodeid);
+                fuse_reply(fd, req->header().unique, -ENOSYS, NULL, 0);
                 return true;
             }
         }
@@ -132,8 +159,7 @@
 private:
     int handle_fuse_lookup(const fuse_in_header& header,
                            const char* name,
-                           fuse_entry_out* out,
-                           uint32_t* /*unused*/) {
+                           FuseResponse<fuse_entry_out>* out) {
         if (header.nodeid != 1) {
             return -ENOENT;
         }
@@ -148,19 +174,19 @@
             return -ENOENT;
         }
 
-        out->nodeid = n;
-        out->attr_valid = 10;
-        out->entry_valid = 10;
-        out->attr.ino = n;
-        out->attr.mode = S_IFREG | 0777;
-        out->attr.size = size;
+        out->prepare_buffer();
+        out->data()->nodeid = n;
+        out->data()->attr_valid = 10;
+        out->data()->entry_valid = 10;
+        out->data()->attr.ino = n;
+        out->data()->attr.mode = S_IFREG | 0777;
+        out->data()->attr.size = size;
         return 0;
     }
 
     int handle_fuse_init(const fuse_in_header&,
                          const fuse_init_in* in,
-                         fuse_init_out* out,
-                         uint32_t* reply_size) {
+                         FuseResponse<fuse_init_out>* out) {
         // Kernel 2.6.16 is the first stable kernel with struct fuse_init_out
         // defined (fuse version 7.6). The structure is the same from 7.6 through
         // 7.22. Beginning with 7.23, the structure increased in size and added
@@ -172,50 +198,58 @@
             return -1;
         }
 
+        // Before writing |out|, we need to copy data from |in|.
+        const uint32_t minor = in->minor;
+        const uint32_t max_readahead = in->max_readahead;
+
         // We limit ourselves to 15 because we don't handle BATCH_FORGET yet
-        out->minor = std::min(in->minor, 15u);
+        size_t response_size = sizeof(fuse_init_out);
 #if defined(FUSE_COMPAT_22_INIT_OUT_SIZE)
         // FUSE_KERNEL_VERSION >= 23.
 
         // If the kernel only works on minor revs older than or equal to 22,
         // then use the older structure size since this code only uses the 7.22
         // version of the structure.
-        if (in->minor <= 22) {
-            *reply_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
+        if (minor <= 22) {
+            response_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
         }
-#else
-        // Don't drop this line to prevent an 'unused' compile error.
-        *reply_size = sizeof(fuse_init_out);
 #endif
-
-        out->major = FUSE_KERNEL_VERSION;
-        out->max_readahead = in->max_readahead;
-        out->flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
-        out->max_background = 32;
-        out->congestion_threshold = 32;
-        out->max_write = MAX_WRITE;
+        out->prepare_buffer(response_size);
+        out->data()->major = FUSE_KERNEL_VERSION;
+        out->data()->minor = std::min(minor, 15u);
+        out->data()->max_readahead = max_readahead;
+        out->data()->flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
+        out->data()->max_background = 32;
+        out->data()->congestion_threshold = 32;
+        out->data()->max_write = MAX_WRITE;
 
         return 0;
     }
 
     int handle_fuse_getattr(const fuse_in_header& header,
                             const fuse_getattr_in* /* in */,
-                            fuse_attr_out* out,
-                            uint32_t* /*unused*/) {
-        if (header.nodeid != 1) {
-            return -ENOENT;
+                            FuseResponse<fuse_attr_out>* out) {
+        out->prepare_buffer();
+        out->data()->attr_valid = 10;
+        out->data()->attr.ino = header.nodeid;
+        if (header.nodeid == 1) {
+            out->data()->attr.mode = S_IFDIR | 0777;
+            out->data()->attr.size = 0;
+        } else {
+            int64_t size = get_file_size(header.nodeid);
+            if (size < 0) {
+                return -ENOENT;
+            }
+            out->data()->attr.mode = S_IFREG | 0777;
+            out->data()->attr.size = size;
         }
-        out->attr_valid = 1000 * 60 * 10;
-        out->attr.ino = header.nodeid;
-        out->attr.mode = S_IFDIR | 0777;
-        out->attr.size = 0;
+
         return 0;
     }
 
     int handle_fuse_open(const fuse_in_header& header,
                          const fuse_open_in* /* in */,
-                         fuse_open_out* out,
-                         uint32_t* /*unused*/) {
+                         FuseResponse<fuse_open_out>* out) {
         if (handles_.size() >= NUM_MAX_HANDLES) {
             // Too many open files.
             return -EMFILE;
@@ -224,68 +258,66 @@
         do {
            handle = handle_counter_++;
         } while (handles_.count(handle) != 0);
-
         handles_.insert(std::make_pair(handle, header.nodeid));
-        out->fh = handle;
+
+        out->prepare_buffer();
+        out->data()->fh = handle;
         return 0;
     }
 
     int handle_fuse_read(const fuse_in_header& /* header */,
                          const fuse_read_in* in,
-                         void* out,
-                         uint32_t* reply_size) {
+                         FuseResponse<void>* out) {
+        if (in->size > MAX_READ) {
+            return -EINVAL;
+        }
         const std::map<uint32_t, uint64_t>::iterator it = handles_.find(in->fh);
         if (it == handles_.end()) {
             return -EBADF;
         }
-        const int64_t result = get_object_bytes(
-                it->second,
-                in->offset,
-                in->size,
-                out);
+        uint64_t offset = in->offset;
+        uint32_t size = in->size;
+
+        // Overwrite the size after writing data.
+        out->prepare_buffer(0);
+        const int64_t result = get_object_bytes(it->second, offset, size, out->data());
         if (result < 0) {
             return -EIO;
         }
-        *reply_size = static_cast<size_t>(result);
+        out->set_size(result);
         return 0;
     }
 
     int handle_fuse_release(const fuse_in_header& /* header */,
                             const fuse_release_in* in,
-                            void* /* out */,
-                            uint32_t* /* reply_size */) {
+                            FuseResponse<void>* /* out */) {
         handles_.erase(in->fh);
         return 0;
     }
 
     int handle_fuse_flush(const fuse_in_header& /* header */,
                           const void* /* in */,
-                          void* /* out */,
-                          uint32_t* /* reply_size */) {
+                          FuseResponse<void>* /* out */) {
         return 0;
     }
 
     template <typename T, typename S>
     void invoke_handler(int fd,
-                        const FuseRequest& request,
+                        FuseRequest* request,
                         int (AppFuse::*handler)(const fuse_in_header&,
                                                 const T*,
-                                                S*,
-                                                uint32_t*),
-                        uint32_t reply_size = sizeof(S)) {
-        char reply_data[reply_size];
-        memset(reply_data, 0, reply_size);
+                                                FuseResponse<S>*)) {
+        FuseResponse<S> response(request->data());
         const int reply_code = (this->*handler)(
-                request.header(),
-                static_cast<const T*>(request.data()),
-                reinterpret_cast<S*>(reply_data),
-                &reply_size);
+                request->header(),
+                static_cast<const T*>(request->data()),
+                &response);
         fuse_reply(
                 fd,
-                request.header().unique,
+                request->header().unique,
                 reply_code,
-                reply_data,
-                reply_size);
+                request->data(),
+                response.size());
     }
 
     int64_t get_file_size(int inode) {
@@ -303,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;
         }
@@ -348,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.");
@@ -378,7 +410,7 @@
             continue;
         }
 
-        if (!appfuse.handle_fuse_request(fd, request)) {
+        if (!appfuse.handle_fuse_request(fd, &request)) {
             return JNI_TRUE;
         }
     }
diff --git a/packages/MtpDocumentsProvider/proguard.flags b/packages/MtpDocumentsProvider/proguard.flags
new file mode 100644
index 0000000..e660121
--- /dev/null
+++ b/packages/MtpDocumentsProvider/proguard.flags
@@ -0,0 +1,4 @@
+# Keeps methods that are invoked by JNI.
+-keepclassmembers class * {
+  @com.android.mtp.annotations.UsedByNative *;
+}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
index 5ffd7cf..1300c47 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
@@ -21,39 +21,37 @@
 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;
 import java.io.IOException;
 
-/**
- * TODO: Remove VisibleForTesting class.
- */
-@VisibleForTesting
 public class AppFuse {
     static {
         System.loadLibrary("appfuse_jni");
     }
 
+    /**
+     * Max read amount specified at the FUSE kernel implementation.
+     * The value is copied from sdcard.c.
+     */
+    static final int MAX_READ = 128 * 1024;
+
     private final String mName;
     private final Callback mCallback;
-    private final Thread mMessageThread;
+    private Thread mMessageThread;
     private ParcelFileDescriptor mDeviceFd;
 
-    @VisibleForTesting
     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());
-            }
-        });
     }
 
-    @VisibleForTesting
-    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();
     }
 
@@ -72,11 +70,6 @@
         }
     }
 
-    /**
-     * @param i
-     * @throws FileNotFoundException
-     */
-    @VisibleForTesting
     public ParcelFileDescriptor openFile(int i) throws FileNotFoundException {
         return ParcelFileDescriptor.open(new File(
                 getMountPoint(),
@@ -84,7 +77,6 @@
                 ParcelFileDescriptor.MODE_READ_ONLY);
     }
 
-    @VisibleForTesting
     File getMountPoint() {
         return new File("/mnt/appfuse/" + Process.myUid() + "_" + mName);
     }
@@ -94,7 +86,7 @@
         byte[] getObjectBytes(int inode, long offset, int size) throws IOException;
     }
 
-    @VisibleForTesting
+    @UsedByNative("com_android_mtp_AppFuse.cpp")
     private long getFileSize(int inode) {
         try {
             return mCallback.getFileSize(inode);
@@ -103,8 +95,11 @@
         }
     }
 
-    @VisibleForTesting
+    @UsedByNative("com_android_mtp_AppFuse.cpp")
     private byte[] getObjectBytes(int inode, long offset, int size) {
+        if (offset < 0 || size < 0 || size > MAX_READ) {
+            return null;
+        }
         try {
             return mCallback.getObjectBytes(inode, offset, size);
         } catch (IOException e) {
@@ -113,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 3573536..3381656 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.mtp;
 
+import static com.android.internal.util.Preconditions.checkArgument;
+
 import android.content.ContentResolver;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
@@ -26,6 +28,7 @@
 import android.mtp.MtpObjectInfo;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
+import android.os.storage.StorageManager;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsContract;
@@ -34,6 +37,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -68,6 +72,7 @@
     private RootScanner mRootScanner;
     private Resources mResources;
     private MtpDatabase mDatabase;
+    private AppFuse mAppFuse;
 
     /**
      * Provides singleton instance to MtpDocumentsService.
@@ -85,6 +90,14 @@
         mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
         mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_FILE);
         mRootScanner = new RootScanner(mResolver, mResources, mMtpManager, mDatabase);
+        mAppFuse = new AppFuse(TAG, new AppFuseCallback());
+        // TODO: Mount AppFuse on demands.
+        try {
+            mAppFuse.mount(getContext().getSystemService(StorageManager.class));
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to start app fuse.", e);
+            return false;
+        }
         resume();
         return true;
     }
@@ -147,16 +160,27 @@
         try {
             switch (mode) {
                 case "r":
-                    return getPipeManager(identifier).readDocument(mMtpManager, identifier);
+                    final long fileSize = getFileSize(documentId);
+                    // MTP getPartialObject operation does not support files that are larger than 4GB.
+                    // Fallback to non-seekable file descriptor.
+                    // TODO: Use getPartialObject64 for MTP devices that support Android vendor
+                    // extension.
+                    if (fileSize <= 0xffffffff) {
+                        return mAppFuse.openFile(Integer.parseInt(documentId));
+                    } else {
+                        return getPipeManager(identifier).readDocument(mMtpManager, identifier);
+                    }
                 case "w":
                     // TODO: Clear the parent document loader task (if exists) and call notify
                     // when writing is completed.
                     return getPipeManager(identifier).writeDocument(
                             getContext(), mMtpManager, identifier);
-                default:
-                    // TODO: Add support for seekable files.
+                case "rw":
+                    // TODO: Add support for "rw" mode.
                     throw new UnsupportedOperationException(
-                            "The provider does not support seekable file.");
+                            "The provider does not support 'rw' mode.");
+                default:
+                    throw new IllegalArgumentException("Unknown mode for openDocument: " + mode);
             }
         } catch (IOException error) {
             throw new FileNotFoundException(error.getMessage());
@@ -330,6 +354,21 @@
         return getDeviceToolkit(identifier.mDeviceId).mDocumentLoader;
     }
 
+    private long getFileSize(String documentId) throws FileNotFoundException {
+        final Cursor cursor = mDatabase.queryDocument(
+                documentId,
+                MtpDatabase.strings(Document.COLUMN_SIZE, Document.COLUMN_DISPLAY_NAME));
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
+            } else {
+                throw new FileNotFoundException();
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
     private static class DeviceToolkit {
         public final PipeManager mPipeManager;
         public final DocumentLoader mDocumentLoader;
@@ -339,4 +378,21 @@
             mDocumentLoader = new DocumentLoader(manager, resolver, database);
         }
     }
+
+    private class AppFuseCallback implements AppFuse.Callback {
+        final byte[] mBytes = new byte[AppFuse.MAX_READ];
+
+        @Override
+        public byte[] getObjectBytes(int inode, long offset, int size) throws IOException {
+            final Identifier identifier = mDatabase.createIdentifier(Integer.toString(inode));
+            mMtpManager.getPartialObject(
+                    identifier.mDeviceId, identifier.mObjectHandle, (int) offset, size, mBytes);
+            return mBytes;
+        }
+
+        @Override
+        public long getFileSize(int inode) throws FileNotFoundException {
+            return MtpDocumentsProvider.this.getFileSize(String.valueOf(inode));
+        }
+    }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 9c726ba..0d81a30 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -188,6 +188,15 @@
         }
     }
 
+    @VisibleForTesting
+    long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
+            throws IOException {
+        final MtpDevice device = getDevice(deviceId);
+        synchronized (device) {
+            return device.getPartialObject(objectHandle, offset, size, buffer);
+        }
+    }
+
     byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
         final MtpDevice device = getDevice(deviceId);
         synchronized (device) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/annotations/UsedByNative.java b/packages/MtpDocumentsProvider/src/com/android/mtp/annotations/UsedByNative.java
new file mode 100644
index 0000000..a7f295f
--- /dev/null
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/annotations/UsedByNative.java
@@ -0,0 +1,31 @@
+/*
+ * 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.mtp.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that shows the method is used by JNI.
+ */
+@Target(ElementType.METHOD)
+public @interface UsedByNative {
+    /**
+     * JNI file name that uses the method.
+     */
+    String value();
+}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
index 76bd2b5..6354880 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
@@ -28,13 +28,9 @@
 import java.io.IOException;
 import java.util.Arrays;
 
-/**
- * TODO: Enable this test after adding SELinux policies for appfuse.
- */
 @MediumTest
 public class AppFuseTest extends AndroidTestCase {
-
-    public void disabled_testMount() throws ErrnoException, InterruptedException {
+    public void testMount() throws ErrnoException, IOException {
         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
         final AppFuse appFuse = new AppFuse("test", new TestCallback());
         appFuse.mount(storageManager);
@@ -45,7 +41,7 @@
         assertTrue(1 != Os.stat(file.getPath()).st_ino);
     }
 
-    public void disabled_testOpenFile() throws IOException {
+    public void testOpenFile() throws IOException {
         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
         final int INODE = 10;
         final AppFuse appFuse = new AppFuse(
@@ -65,7 +61,7 @@
         appFuse.close();
     }
 
-    public void disabled_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());
@@ -79,7 +75,7 @@
         appFuse.close();
     }
 
-    public void disabled_testReadFile() throws IOException {
+    public void testReadFile() throws IOException {
         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
         final int INODE = 10;
         final byte[] BYTES = new byte[] { 'a', 'b', 'c', 'd', 'e' };
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
index 7527f54..914a4af 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
@@ -21,8 +21,10 @@
 import android.hardware.usb.UsbManager;
 import android.mtp.MtpConstants;
 import android.mtp.MtpEvent;
+import android.mtp.MtpObjectInfo;
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
+import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
 import android.test.InstrumentationTestCase;
 
@@ -98,6 +100,50 @@
         }
     }
 
+    public void testCreateDocumentAndGetPartialObject() throws Exception {
+        int storageId = 0;
+        for (final MtpDeviceRecord record : mManager.getDevices()) {
+            if (record.deviceId == mUsbDevice.getDeviceId()) {
+                storageId = record.roots[0].mStorageId;
+                break;
+            }
+        }
+        assertTrue("Valid storage not found.", storageId != 0);
+
+        final String testFileName = "MtpManagerTest_testFile.txt";
+        for (final int handle : mManager.getObjectHandles(
+                mUsbDevice.getDeviceId(), storageId, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN)) {
+            if (mManager.getObjectInfo(mUsbDevice.getDeviceId(), handle)
+                    .getName().equals(testFileName)) {
+                mManager.deleteDocument(mUsbDevice.getDeviceId(), handle);
+                break;
+            }
+        }
+
+        final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
+        final byte[] expectedBytes = "Hello Android!".getBytes("ascii");
+        try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
+                new ParcelFileDescriptor.AutoCloseOutputStream(fds[1])) {
+            stream.write(expectedBytes);
+        }
+        final int objectHandle = mManager.createDocument(
+                mUsbDevice.getDeviceId(),
+                new MtpObjectInfo.Builder()
+                        .setStorageId(storageId)
+                        .setName(testFileName)
+                        .setCompressedSize(expectedBytes.length)
+                        .setFormat(MtpConstants.FORMAT_TEXT)
+                        .build(),
+                fds[0]);
+        final byte[] bytes = new byte[100];
+        assertEquals(5, mManager.getPartialObject(
+                mUsbDevice.getDeviceId(), objectHandle, 0, 5, bytes));
+        assertEquals("Hello", new String(bytes, 0, 5, "ascii"));
+        assertEquals(8, mManager.getPartialObject(
+                mUsbDevice.getDeviceId(), objectHandle, 6, 100, bytes));
+        assertEquals("Android!", new String(bytes, 0, 8, "ascii"));
+    }
+
     private Context getContext() {
         return getInstrumentation().getContext();
     }
diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml
index 6179b4b..57ba2b6 100644
--- a/packages/PrintSpooler/res/values-af/strings.xml
+++ b/packages/PrintSpooler/res/values-af/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Meer inligting oor hierdie drukker"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Sommige drukdienste is gedeaktiveer."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Kies drukdiens"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Soek tans vir drukkers"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Geen drukdienste is geaktiveer nie"</string>
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
index 2f94e1e..a2182fb 100644
--- a/packages/PrintSpooler/res/values-am/strings.xml
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ተጨማሪ የዚህ አታሚ መረጃ"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"አንዳንድ የህትመት አገልግሎቶች ተሰናክለዋል።"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"የህትመት አገልግሎት ይምረጡ"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"አታሚዎችን በመፈለግ ላይ"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ምንም የህትመት አገልግሎቶች አልነቁም"</string>
diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml
index 29767c3..eab1339 100644
--- a/packages/PrintSpooler/res/values-ar/strings.xml
+++ b/packages/PrintSpooler/res/values-ar/strings.xml
@@ -65,6 +65,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"مزيد من المعلومات حول هذه الطابعة"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"بعض خدمات الطباعة معطَّلة."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"اختر خدمة طباعة"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"البحث عن طابعات"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"لم يتم تمكين أي خدمات طباعة"</string>
diff --git a/packages/PrintSpooler/res/values-az-rAZ/strings.xml b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
index 3316b30..bff477d 100644
--- a/packages/PrintSpooler/res/values-az-rAZ/strings.xml
+++ b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Bu printer haqqında daha ətraflı məlumat"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Bəzi çap xidmətləri deaktiv edilib."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Çap xidmətini seçin"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Printer axtarılır"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Heç bir çap xidməti aktiv edilməyib"</string>
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 86baf10..b28aa29 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Još informacija o ovom štampaču"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Neke usluge štampanja su onemogućene."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Izaberite uslugu štampanja"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Pretraga štampača"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nijedna usluga štampanja nije omogućena"</string>
diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml
index 2c02b74..e8de8ea 100644
--- a/packages/PrintSpooler/res/values-bg/strings.xml
+++ b/packages/PrintSpooler/res/values-bg/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Още информация за този принтер"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Някои услуги за отпечатване са деактивирани."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Избиране на услуга за отпечатване"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Търсене на принтери"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Няма активирани услуги за отпечатване"</string>
diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
index d48d91d..a1ca494 100644
--- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml
+++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"এই মুদ্রকটির বিষয়ে আরো তথ্য"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"কিছু মুদ্রণ পরিষেবা অক্ষম করা হয়েছে৷"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"মুদ্রণ পরিষেবা চয়ন করুন"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"মুদ্রকগুলি অনুসন্ধান করা হচ্ছে"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"মুদ্রণ পরিষেবা সক্ষম নেই"</string>
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
index d0fd75e..aa6f992 100644
--- a/packages/PrintSpooler/res/values-ca/strings.xml
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Més informació sobre aquesta impressora"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Hi ha serveis d\'impressió que estan desactivats."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Selecció del servei d\'impressió"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Cerca d\'impressores"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"No hi ha cap servei d\'impressió activat"</string>
diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml
index bec34ac..4bc22d4 100644
--- a/packages/PrintSpooler/res/values-cs/strings.xml
+++ b/packages/PrintSpooler/res/values-cs/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Další informace o této tiskárně"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Některé tiskové služby nejsou aktivovány."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Zvolte službu tisku"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Vyhledávání tiskáren"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nejsou aktivovány žádné tiskové služby"</string>
diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml
index de29146..b8be624 100644
--- a/packages/PrintSpooler/res/values-da/strings.xml
+++ b/packages/PrintSpooler/res/values-da/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Flere oplysninger om denne printer"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Nogle udskrivningstjenester er deaktiveret."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Vælg udskriftstjeneste"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Søger efter printere"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ingen udskrivningstjenester er aktiveret"</string>
diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
index 054454e..bcb7e73 100644
--- a/packages/PrintSpooler/res/values-de/strings.xml
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Weitere Informationen über diesen Drucker"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Einige Druckdienste sind deaktiviert."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Druckdienst auswählen"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Suche nach Druckern"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Keine Druckdienste aktiviert"</string>
@@ -75,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>
@@ -90,7 +91,7 @@
     <item msgid="3199660090246166812">"Querformat"</item>
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"Fehler beim Schreiben in Datei"</string>
-    <string name="print_error_default_message" msgid="8602678405502922346">"Fehler. Bitte versuchen Sie es erneut."</string>
+    <string name="print_error_default_message" msgid="8602678405502922346">"Fehler. Bitte versuche es erneut."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Erneut versuchen"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Dieser Drucker ist momentan nicht verfügbar."</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Vorschau wird vorbereitet…"</string>
diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml
index abae961..d9a4aeb 100644
--- a/packages/PrintSpooler/res/values-el/strings.xml
+++ b/packages/PrintSpooler/res/values-el/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Περισσότερες πληροφορίες σχετικά με αυτόν τον εκτυπωτή"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Κάποιες υπηρ. εκτύπωσης είναι απενεργοποιημένες."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Επιλέξτε υπηρεσία εκτύπωσης"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Αναζήτηση για εκτυπωτές"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Δεν έχουν ενεργοποιηθεί υπηρεσίες εκτύπωσης"</string>
diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml
index b656dcd..d8a9437 100644
--- a/packages/PrintSpooler/res/values-en-rAU/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"More information about this printer"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Some print services are disabled."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"No print services enabled"</string>
diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml
index b656dcd..d8a9437 100644
--- a/packages/PrintSpooler/res/values-en-rGB/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"More information about this printer"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Some print services are disabled."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"No print services enabled"</string>
diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml
index b656dcd..d8a9437 100644
--- a/packages/PrintSpooler/res/values-en-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"More information about this printer"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Some print services are disabled."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"No print services enabled"</string>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 712bb80..19c695b 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Más información sobre esta impresora"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Hay servicios de impresión inhabilitados."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Elegir servicio de impresión"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Buscando impresoras"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"No hay servicios de impresión habilitados"</string>
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
index dfd6a62..d13ccda 100644
--- a/packages/PrintSpooler/res/values-es/strings.xml
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Más información sobre esta impresora"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Algunos servicios de impresión están inhabilitados."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Seleccionar servicio de impresión"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Buscando impresoras"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"No hay servicios de impresión habilitados"</string>
diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml
index 7b962af..f03eb37 100644
--- a/packages/PrintSpooler/res/values-et-rEE/strings.xml
+++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Lisateave selle printeri kohta"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Mõned printimisteenused on keelatud."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Prinditeenuse valimine"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Printerite otsimine"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ühtegi printimisteenust pole lubatud"</string>
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index 4551cc2..d4255e2 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Informazio gehiago inprimagailuari buruz"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Desgaituta daude inprimatzeko zerbitzu batzuk."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Aukeratu inprimatze-zerbitzua"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Inprimagailuak bilatzen"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ez dago gaituta inprimatzeko zerbitzurik"</string>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index d85978d..907123c 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"اطلاعات بیشتر درباره چاپگر"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"بعضی از خدمات چاپ غیرفعال هستند."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"انتخاب سرویس چاپ"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"درحال جستجوی چاپگرها"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"هیچ خدمات چاپی فعال نیست"</string>
diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml
index 4472459..f57b884 100644
--- a/packages/PrintSpooler/res/values-fi/strings.xml
+++ b/packages/PrintSpooler/res/values-fi/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Lisätietoja tästä tulostimesta"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Osa tulostuspalveluista on poistettu käytöstä."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Valitse tulostuspalvelu"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Etsitään tulostimia"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ei käytössä olevia tulostuspalveluita"</string>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index 1d45315..949ba55 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Plus d\'information sur cette imprimante"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Certains services d\'impression sont désactivés."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Sélectionner le service d\'impression"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Recherche d\'imprimantes en cours..."</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Aucun service d\'impression activé"</string>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
index df7dfef..1fcc040 100644
--- a/packages/PrintSpooler/res/values-fr/strings.xml
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Plus d\'informations sur cette imprimante"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Certains services d\'impression sont désactivés."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Sélectionner le service d\'impression"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Recherche d\'imprimantes en cours"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Aucun service d\'impression activé"</string>
diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml
index eae6450..2e60960 100644
--- a/packages/PrintSpooler/res/values-gl-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Máis información sobre esta impresora"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Algúns servizos de impresión están desactivados."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Escoller servizo de impresión"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Busca de impresoras"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Non hai servizos de impresión activados"</string>
diff --git a/packages/PrintSpooler/res/values-gu-rIN/strings.xml b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
index 8028274..4ba969c 100644
--- a/packages/PrintSpooler/res/values-gu-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"આ પ્રિન્ટર વિશે વધુ માહિતી"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"કેટલીક છાપ સેવાઓ અક્ષમ કરેલ છે."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"પ્રિન્ટ સેવા પસંદ કરો"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"પ્રિન્ટર્સ માટે શોધી રહ્યું છે"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"કોઈ છાપ સેવાઓ સક્ષમ કરેલ નથી"</string>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index 5bfcc6e..1061346 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"इस प्रिंटर के बारे में अधिक जानकारी"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"कुछ प्रिंट सेवाएं अक्षम हैं."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"प्रिंट सेवा चुनें"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर खोज रहा है"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"कोई भी प्रिंट सेवा सक्षम नहीं है"</string>
diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml
index bf244c5..4a7d29f 100644
--- a/packages/PrintSpooler/res/values-hr/strings.xml
+++ b/packages/PrintSpooler/res/values-hr/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Više informacija o ovom pisaču"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Neke su usluge ispisa onemogućene."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Odaberite uslugu ispisa"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje pisača"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nije omogućena nijedna usluga ispisa"</string>
diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml
index 6c608f1..5aae2e4 100644
--- a/packages/PrintSpooler/res/values-hu/strings.xml
+++ b/packages/PrintSpooler/res/values-hu/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"További információ erről a nyomtatóról"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Egyes nyomtatási szolgáltatások le vannak tiltva."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Nyomtatási szolgáltatás kiválasztása"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Nyomtatók keresése"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nincs engedélyezett nyomtatási szolgáltatás"</string>
diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
index 801410b..179c384 100644
--- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml
+++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Հավելյալ տեղեկություններ այս տպիչի մասին"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Տպելու որոշ ծառայությունները կասեցված են:"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Ընտրեք տպելու ծառայությունը"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Տպիչների որոնում"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ակտիվացված տպման ծառայություններ չկան"</string>
diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml
index 227a372..7286f7a 100644
--- a/packages/PrintSpooler/res/values-in/strings.xml
+++ b/packages/PrintSpooler/res/values-in/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Informasi selengkapnya tentang printer ini"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Beberapa layanan cetak dinonaktifkan."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Pilih layanan cetak"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Mencari printer"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Tidak ada layanan cetak yang aktif"</string>
diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml
index f078ff8..9ea49a9 100644
--- a/packages/PrintSpooler/res/values-is-rIS/strings.xml
+++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Frekari upplýsingar um þennan prentara"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Hluti prentþjónustunnar er óvirkur."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Veldu prentþjónustu"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Leitar að prentara"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Engin prentþjónusta er virk"</string>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
index 10b3601..c19d012 100644
--- a/packages/PrintSpooler/res/values-it/strings.xml
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Ulteriori informazioni su questa stampante"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alcuni servizi di stampa sono disattivati."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Scegli servizio di stampa"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Ricerca di stampanti"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Non è stato attivato alcun servizio di stampa"</string>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index 8a04c76..00bf27c 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"מידע נוסף על מדפסת זו"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"שירותי הדפסה מסוימים מושבתים."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"בחר שירות הדפסה"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"מחפש מדפסות"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"לא הופעלו שירותי הדפסה"</string>
diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml
index a132fb1..e0fc79a 100644
--- a/packages/PrintSpooler/res/values-ja/strings.xml
+++ b/packages/PrintSpooler/res/values-ja/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"このプリンタの詳細"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"一部の印刷サービスは無効になっています。"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"印刷サービスの選択"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"プリンタの検索中"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"使用できる印刷サービスがありません"</string>
diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
index 675245b..ad1468a 100644
--- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml
+++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> — <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"დამატებითი ინფორმაცია ამ პრინტერის შესახებ"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"ბეჭდვის ზოგიერთი სერვისი გათიშულია."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"აირჩიეთ ბეჭდვის სერვისი"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"მიმდინარეობს პრინტერების ძიება"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ბეჭდვის სერვისები გააქტიურებული არ არის"</string>
diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
index 4c7c4f4..d0337a6 100644
--- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
+++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Осы принтер туралы қосымша ақпарат"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Кейбір басып шығару қызметтері өшірілген."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Принтер қызметін таңдау"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтерлерді іздеу"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Басып шығару қызметтері қосылмаған"</string>
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
index fac7c0c..c9431e9 100644
--- a/packages/PrintSpooler/res/values-km-rKH/strings.xml
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ព័ត៌មានបន្ថែមអំពីម៉ាស៊ីបោះពុម្ពនេះ"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"សេវាកម្មបោះពុម្ពមួយចំនួនត្រូវបានបិទដំណើរការ"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"ជ្រើស​សេវា​បោះពុម្ព"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"ស្វែងរក​ម៉ាស៊ីន​បោះពុម្ព"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"គ្មានការបើកដំណើរការសេវាបោះពុម្ពទេ"</string>
diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
index 61279fc..fc5149a 100644
--- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ಈ ಪ್ರಿಂಟರ್ ಬಗ್ಗೆ ಇನ್ನಷ್ಟು ಮಾಹಿತಿ"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"ಕೆಲವು ಮುದ್ರಣ ಸೇವೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"ಮುದ್ರಣ ಸೇವೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"ಪ್ರಿಂಟರ್‌‌ಗಳಿಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ಯಾವುದೇ ಮುದ್ರಣ ಸೇವೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿಲ್ಲ"</string>
diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml
index fe47e55..2faff1f 100644
--- a/packages/PrintSpooler/res/values-ko/strings.xml
+++ b/packages/PrintSpooler/res/values-ko/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"이 프린터에 대한 정보 더보기"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"프린트 서비스 일부가 사용 중지되었습니다."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"인쇄 서비스 선택"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"프린터 검색 중"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"사용 가능한 프린트 서비스 없음"</string>
diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
index 79b38d1..a01e4a8 100644
--- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml
+++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Бул принтер жөнүндө көбүрөөк маалымат"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Басып чыгаруу кызматтарынын айрымы өчүрүлгөн."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Принтер кызматын тандоо"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтерлер изделүүдө"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Принтер-кызматтары иштетилген эмес"</string>
diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
index 3140a25..b5d13b5 100644
--- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml
+++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ຂໍ້ມູນເພີ່ມເຕີມກ່ຽວກັບເຄື່ອງພິມນີ້"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"ບາງການບໍລິການພິມຖືກປິດນຳໃຊ້."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"ເລືອກບໍລິການການພິມ"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"ກຳລັງຊອກຫາເຄື່ອງພິມ"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ບໍ່​ມີ​ການ​ບໍ​ລິ​ການ​ພິມ​ເປີດ​ໃຊ້​ງານ​ໄວ້"</string>
diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml
index 4f0772e..3b8f143 100644
--- a/packages/PrintSpooler/res/values-lt/strings.xml
+++ b/packages/PrintSpooler/res/values-lt/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"„<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g>“ – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Daugiau informacijos apie šį spausdintuvą"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Kai kurios spausdinimo paslaugos išjungtos."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Pasirinkite spausdinimo paslaugą"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Ieškoma spausdintuvų"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Neįgalinta jokių spausdinimo paslaugų"</string>
diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml
index 0efa50f..762d0bd 100644
--- a/packages/PrintSpooler/res/values-lv/strings.xml
+++ b/packages/PrintSpooler/res/values-lv/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> — <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Plašāka informācija par šo printeri"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Daži drukas pakalpojumi ir atspējoti."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Izvēlieties drukāšanas pakalpojumu"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Printeru meklēšana"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nav iespējots neviens drukas pakalpojums"</string>
diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
index 2805dee..de6d3e9 100644
--- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml
+++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Повеќе информации за овој печатач"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Некои услуги за печатење се оневозможени."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Избери услуга печатење"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Пребарување печатачи"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Нема овозможени услуги за печатење"</string>
diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
index 9617a7a..7a33e14 100644
--- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ഈ പ്രിന്ററിനെ കുറിച്ചുള്ള കൂടുതൽ വിവരങ്ങൾ"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"ചില പ്രിന്റ് സേവനങ്ങൾ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"പ്രിന്റ് സേവനം തിരഞ്ഞെടുക്കുക"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"പ്രിന്ററുകൾക്കായി തിരയുന്നു"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"പ്രിന്റ് സേവനങ്ങളൊന്നും പ്രവർത്തനക്ഷമാക്കിയിട്ടില്ല"</string>
diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
index 59bb9bf..c94e56d 100644
--- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml
+++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Энэ хэвлэгчийн талаарх дэлгэрэнгүй мэдээлэл"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Зарим хэвлэх үйлчилгээг идэвхгүй болгосон байна."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Хэвлэх үйлчилгээг сонгох"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтер хайж байна"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Хэвлэх үйлчилгээг идэвхжүүлээгүй"</string>
diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
index 2b6661e..ab25010 100644
--- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"या प्रिंटर विषयी अधिक माहिती"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"काही मुद्रण सेवा अक्षम केल्या आहेत."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"मुद्रण सेवा निवडा"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर शोधत आहे"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"कोणत्याही मुद्रण सेवा सक्षम केलेल्या नाहीत"</string>
diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
index c066627..917ae8a 100644
--- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml
+++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Maklumat lanjut tentang pencetak ini"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Sesetengah perkhidmatan cetak dilumpuhkan."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Pilih perkhidmatan cetak"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Mencari pencetak"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Perkhidmatan cetak tidak didayakan"</string>
diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml
index a63e85e..4d4c95b 100644
--- a/packages/PrintSpooler/res/values-my-rMM/strings.xml
+++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ဤပရင်တာ အကြောင်း ပိုမိုလေ့လာပါ"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"ပရင့်ထုတ်ရေး အချို့ဝန်ဆောင်မှုများကို ပိတ်ထားပါသည်။"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"စာထုတ်ရန် ဝန်ဆောင်မှုကို ရွေးချယ်ပါ"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"စာထုတ်စက်များကို ရှာနေပါသည်"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ပုံနှိပ်ထုတ်ယူရေး ဝန်ဆောင်မှုများ ဖွင့်မထားပါ"</string>
diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml
index 8128011..9efa5d1 100644
--- a/packages/PrintSpooler/res/values-nb/strings.xml
+++ b/packages/PrintSpooler/res/values-nb/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Mer informasjon om denne printeren"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Noen utskriftstjenester er slått av."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Velg utskriftstjeneste"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Søker etter skrivere"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ingen utskriftstjenester er slått på"</string>
diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
index 89b2fbb..281a65d 100644
--- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml
+++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"यस प्रिन्टरको बारेमा थप जानकारी"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"केही मुद्रण सेवाहरू असक्षम छन्।"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"प्रिन्ट सेवा छनौट गर्नुहोस्"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिन्टरहरू खोज्दै"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"कुनै पनि मुद्रण सेवाहरू सक्रिय छैनन्"</string>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
index 70b93e6..eef9880 100644
--- a/packages/PrintSpooler/res/values-nl/strings.xml
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Meer informatie over deze printer"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Sommige afdrukservices zijn uitgeschakeld."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Afdrukservice kiezen"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Printers zoeken"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Geen afdrukservices ingeschakeld"</string>
diff --git a/packages/PrintSpooler/res/values-pa-rIN/strings.xml b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
index da81919..7d7860c 100644
--- a/packages/PrintSpooler/res/values-pa-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ਇਸ ਪ੍ਰਿੰਟਰ ਬਾਰੇ ਹੋਰ ਜਾਣਕਾਰੀ"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"ਕੁਝ ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਹਨ।"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"ਪ੍ਰਿੰਟ ਸੇਵਾ ਚੁਣੋ"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"ਪ੍ਰਿੰਟਰ ਖੋਜ ਰਿਹਾ ਹੈ"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਯੋਗ ਨਹੀਂ ਬਣਾਈਆਂ ਗਈਆਂ"</string>
diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml
index b7613cf..6837edf 100644
--- a/packages/PrintSpooler/res/values-pl/strings.xml
+++ b/packages/PrintSpooler/res/values-pl/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Więcej informacji o tej drukarce"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Niektóre usługi drukowania są wyłączone."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Wybierz usługę drukowania"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Szukanie drukarek"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Brak włączonych usług drukowania"</string>
diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
index 199f304..c9713c9 100644
--- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Mais informações sobre essa impressora"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alguns serviços de impressão estão desativados."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Selecione o serviço de impressão"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Procurando impressoras"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nenhum serviço de impressão ativado"</string>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index ea94c55..9fabc0f 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Mais informações acerca desta impressora"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alguns serviços de impressão estão desativados."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Escolher o serviço de impressão"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"A procurar impressoras"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nenhum serviço de impressão ativado"</string>
diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml
index 199f304..c9713c9 100644
--- a/packages/PrintSpooler/res/values-pt/strings.xml
+++ b/packages/PrintSpooler/res/values-pt/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Mais informações sobre essa impressora"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alguns serviços de impressão estão desativados."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Selecione o serviço de impressão"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Procurando impressoras"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nenhum serviço de impressão ativado"</string>
diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml
index 1c74aab..7364eb0 100644
--- a/packages/PrintSpooler/res/values-ro/strings.xml
+++ b/packages/PrintSpooler/res/values-ro/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Mai multe informații despre această imprimantă"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Unele servicii de printare sunt dezactivate."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Alegeți serviciul de printare"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Se caută imprimante"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Niciun serviciu de printare activat"</string>
diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml
index e900ab9..d3d0d3f 100644
--- a/packages/PrintSpooler/res/values-ru/strings.xml
+++ b/packages/PrintSpooler/res/values-ru/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Подробные сведения о принтере"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Некоторые службы печати отключены."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Выберите службу печати"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Поиск принтеров…"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Службы печати недоступны"</string>
diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml
index 5731849..610442d 100644
--- a/packages/PrintSpooler/res/values-si-rLK/strings.xml
+++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"මෙම මුද්‍රණ යන්ත්‍රය ගැන තවත් තොරතුරු"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"සමහර මුද්‍රණ සේවා අබලයි."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"මුද්‍රණ සේවාව තෝරන්න"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"මුද්‍රණ යන්ත්‍ර සොයමින්"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"මුද්‍රණ සේවා සබල නැත"</string>
diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml
index 1c7b740..603d1d2 100644
--- a/packages/PrintSpooler/res/values-sk/strings.xml
+++ b/packages/PrintSpooler/res/values-sk/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Ďalšie informácie o tejto tlačiarni"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Niektoré tlačové služby sú vypnuté."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Výber tlačovej služby"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Vyhľadávanie tlačiarní"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Žiadne tlačové služby nie sú aktivované"</string>
diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml
index 4c794dc..4a08269 100644
--- a/packages/PrintSpooler/res/values-sl/strings.xml
+++ b/packages/PrintSpooler/res/values-sl/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Več informacij o tem tiskalniku"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Nekatere tiskalne storitve so onemogočene."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Izberite tiskalno storitev"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Iskanje tiskalnikov"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ni omogočenih tiskalnih storitev"</string>
diff --git a/packages/PrintSpooler/res/values-sq-rAL/strings.xml b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
index aff55f6..b0902ef 100644
--- a/packages/PrintSpooler/res/values-sq-rAL/strings.xml
+++ b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Më shumë informacione mbi këtë printer"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Disa shërbime printimi janë çaktivizuar."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Zgjidh shërbimin e printimit"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Po kërkon për printerë"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Nuk ka shërbime printimi të aktivizuara"</string>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index 043048e..feb2940 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Још информација о овом штампачу"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Неке услуге штампања су онемогућене."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Изаберите услугу штампања"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Претрага штампача"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Ниједна услуга штампања није омогућена"</string>
diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml
index fd8581f..cf398c7 100644
--- a/packages/PrintSpooler/res/values-sv/strings.xml
+++ b/packages/PrintSpooler/res/values-sv/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Mer information om den här skrivaren"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Några utskriftstjänster har inaktiverats."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Välj utskriftstjänst"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Söker efter skrivare"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Inga utskriftstjänster har aktiverats"</string>
diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml
index 0950f57..7e00b70 100644
--- a/packages/PrintSpooler/res/values-sw/strings.xml
+++ b/packages/PrintSpooler/res/values-sw/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Maelezo zaidi kuhusu printa hii"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Baadhi ya huduma za uchapishaji zimezimwa."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Chagua huduma ya printa"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Inatafuta printa"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Huduma za kuchapisha hazijawashwa"</string>
diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
index bf6feae..ae0b774 100644
--- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"இந்தப் பிரிண்டர் பற்றிய கூடுதல் தகவல்"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"சில அச்சுப் பொறிகள் முடக்கப்பட்டன."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"அச்சுப் பொறியைத் தேர்வுசெய்யவும்"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"அச்சுப்பொறிகளைத் தேடுகிறது"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"அச்சுப் பொறிகள் இல்லை"</string>
diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml
index 4d14b8c..5fd8d60 100644
--- a/packages/PrintSpooler/res/values-te-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ఈ ప్రింటర్ గురించి మరింత సమాచారం"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"కొన్ని ముద్రణ సేవలు నిలిపివేయబడ్డాయి."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"ముద్రణ సేవను ఎంచుకోండి"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"ప్రింటర్‌ల కోసం శోధిస్తోంది"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ముద్రణ సేవలు ఏవీ ప్రారంభించలేదు"</string>
diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml
index e1f82e1..ebd5e2a 100644
--- a/packages/PrintSpooler/res/values-th/strings.xml
+++ b/packages/PrintSpooler/res/values-th/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"ข้อมูลเพิ่มเติมเกี่ยวกับเครื่องพิมพ์นี้"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"บริการพิมพ์บางอย่างถูกปิดใช้"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"เลือกบริการพิมพ์"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"กำลังค้นหาเครื่องพิมพ์"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"ไม่ได้เปิดใช้บริการพิมพ์"</string>
diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml
index 052d8cc..ebe869b 100644
--- a/packages/PrintSpooler/res/values-tl/strings.xml
+++ b/packages/PrintSpooler/res/values-tl/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Higit pang impormasyon tungkol sa printer na ito"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Naka-disable ang ilang serbisyo sa pag-print."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Pumili ng serbisyo ng pag-print"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Naghahanap ng mga printer"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Walang mga naka-enable na serbisyo sa pag-print"</string>
diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml
index 7f9e6f5..9cd42ab 100644
--- a/packages/PrintSpooler/res/values-tr/strings.xml
+++ b/packages/PrintSpooler/res/values-tr/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Bu yazıcıyla ilgili daha fazla bilgi"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Bazı yazdırma hizmetleri devre dışı."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Yazdırma hizmetini seçin"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Yazıcılar aranıyor"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Etkin yazıcı hizmeti yok"</string>
diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml
index d34aa2a..1082147 100644
--- a/packages/PrintSpooler/res/values-uk/strings.xml
+++ b/packages/PrintSpooler/res/values-uk/strings.xml
@@ -63,6 +63,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Докладніше про цей принтер"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Деякі служби друку вимкнено."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Вибрати службу друку"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Пошук принтерів"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Немає служб друку"</string>
diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
index ccf6f56..56f1093 100644
--- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml
+++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"اس پرنٹر کے بارے میں مزید معلومات"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"پرنٹ کی کچھ سروسز غیر فعال ہیں۔"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"پرنٹ سروس منتخب کریں"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"پرنٹرز تلاش کر رہا ہے"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"کوئی پرنٹ سروس فعال نہیں"</string>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index d1fc47f..30b218e 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Printer haqida batafsil ma’lumot"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Bir qancha chop etish xizmatlari o‘chirilgan."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Chop etish xizmatini tanlang"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Printerlar qidirilmoqda"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Hech qaysi chop etish xizmati yoqilmagan"</string>
diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml
index eb5de95..32aaf63 100644
--- a/packages/PrintSpooler/res/values-vi/strings.xml
+++ b/packages/PrintSpooler/res/values-vi/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Thông tin khác về máy in này"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Một số dịch vụ in bị vô hiệu hóa."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Chọn dịch vụ in"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Đang tìm kiếm máy in"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Chưa kích hoạt dịch vụ in nào"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
index e39849e..42cf3b1 100644
--- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"关于此打印机的更多信息"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"部分打印服务已停用。"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"选择打印服务"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜索打印机"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"未启用任何打印服务"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
index 1148226..0a458ad 100644
--- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"此打印機詳情"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"已停用部分列印服務。"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"選擇列印服務"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜尋打印機"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"沒有已啟用的列印服務"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
index c0dd3de..7a30011 100644
--- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"查看這台印表機的詳細資訊"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"部分列印服務已停用。"</string>
     <string name="choose_print_service" msgid="3740309762324459694">"選擇列印服務"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜尋印表機"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"未啟用任何列印服務"</string>
diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml
index 231b1bf..f57b58c 100644
--- a/packages/PrintSpooler/res/values-zu/strings.xml
+++ b/packages/PrintSpooler/res/values-zu/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="printer_info_desc" msgid="7181988788991581654">"Olunye ulwazi mayelana nale phrinta"</string>
+    <string name="print_services_disabled_toast" msgid="1205302482388937547">"Amanye amasevisi wokuphrinta akhutshaziwe."</string>
     <string name="choose_print_service" msgid="3740309762324459694">"Khetha isevisi yephrinta"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Isesha amaphrinta"</string>
     <string name="print_no_print_services" msgid="8561247706423327966">"Amasevisi ephrinta akavuliwe."</string>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 9c1cf64..811adda 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -1964,7 +1964,7 @@
                                 && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE)
                                 || (mPrinter.getCapabilities() == null
                                 && printer.getCapabilities() != null);
-                mPrinter.copyFrom(printer);
+                mPrinter = printer;
             }
 
             if (available) {
@@ -2394,7 +2394,7 @@
 
             mPrinterAvailabilityDetector.updatePrinter(newPrinterState);
 
-            oldPrinterState.copyFrom(newPrinterState);
+            mCurrentPrinter = newPrinterState;
 
             if ((isActive && gotCapab) || (becameActive && hasCapab)) {
                 if (hasCapab && capabChanged) {
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-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index ebe8752..e7ae858 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -247,8 +247,8 @@
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"Laat enige program na ekstern geskryf word, ongeag manifeswaardes"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"Verplig verstelbare groottes vir aktiwiteite"</string>
     <string name="force_resizable_activities_summary" msgid="4508217476997182216">"Maak grootte van alle aktiwiteite verstelbaar vir veelvuldige vensters, ongeag manifeswaardes."</string>
-    <string name="enable_freeform_support" msgid="1461893351278940416">"Aktiveer vormvrye vensters"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktiveer steun vir eksperimentele vormvrye vensters."</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"Aktiveer vormvrye-Windows"</string>
+    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktiveer steun vir eksperimentele vormvrye-Windows."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Werkskerm-rugsteunwagwoord"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Volle rekenaarrugsteune word nie tans beskerm nie"</string>
     <string name="local_backup_password_summary_change" msgid="2731163425081172638">"Raak om die wagwoord vir volledige rekenaarrugsteune te verander of te verwyder"</string>
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Outomaties"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Stel WebView-implementering"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Die gekose WebView-toepassing is gedeaktiveer, maar moet geaktiveer wees om gebruik te word. Wil jy dit aktiveer?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Skakel om na lêerenkripsie"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Skakel om …"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Lêerenkripsie is reeds uitgevoer"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurregstelling"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierdie kenmerk is eksperimenteel en kan werkverrigting beïnvloed."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – sowat <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol op WS"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol oor USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol vanaf draadloos"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laai tans op WS"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laai tans oor USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Laai tans draadloos"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Laai nie"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laai nie"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index e33d0fa..beac0a1 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"የቀለም ማስተካከያ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ይህ ባህሪ የሙከራ ነውና አፈጻጸም ላይ ተጽዕኖ ሊኖረው ይችላል።"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ገደማ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> እስከሚሞላ ድረስ"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በኤሲ ላይ እስከሚሞላ ድረስ"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በዩኤስቢ ላይ እስከሚሞላ ድረስ"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በገመድ አልባ ላይ እስከሚሞላ ድረስ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ያልታወቀ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ኃይል በመሙላት ላይ"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"በኤሲ ሃይል በመሙላት ላይ"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"በዩኤስቢ ሃይል በመሙላት ላይ"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"በገመድ አልባ ሃይል በመሙላት ላይ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ባትሪ እየሞላ አይደለም"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ኃይል  እየሞላ አይደለም"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 71761b9..2386cb6 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحيح الألوان"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"هذه الميزة تجريبية وقد تؤثر في الأداء."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال باستخدام التيار المتردد"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"‏<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال عبر USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال بالشحن اللاسلكي"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"غير معروف"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"شحن"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"جارٍ الشحن بتيار متردد"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"‏جارٍ الشحن عبر USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"جارٍ الشحن لاسلكيًا"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"لا يتم الشحن"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index b5a7181..273ea30 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Avtomatik"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView icrası"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView icrasını ayarlayın"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Seçilmiş WebView icrası deaktiv edildi, istifadəsi üçün aktiv edilməlidir, aktivləşdirmək istəyirsiniz?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Fayl şifrələnməsinə çevirin"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Çevirin..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Fayl artıq şifrələnib"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rəng düzəlişi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya eksperimentaldır və performansa təsir edə bilər."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> dolana qədər"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC üzərindən dolana qədər"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB üzərindən dolana qədər"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> naqilsiz üzərindən dolana qədər"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Naməlum"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Dəyişən cərəyanda qidalanır"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB üzərindən qidalanır"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Naqilsiz qidalanır"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Doldurulmur"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Enerji doldurulmur"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 3fd4f7f..4f95052 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatski"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Primena WebView-a"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Podesite primenu WebView-a"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Izabrana primena WebView-a je onemogućena, a mora da bude omogućena radi korišćenja. Želite li da je omogućite?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konvertuj u šifrovanje datoteka"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertuj..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Već se koristi šifrovanje datoteka"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boja"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo oko <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni punjačem"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni preko USB-a"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni bežično"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Punjenje preko punjača"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index cd4529f..74c58a5 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекция на цветове"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – приблизително оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане при променлив ток"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> ˜– <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане през USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно безжично зареждане"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарежда се"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зареждане при AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зареждане през USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Безжично зареждане"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Не се зарежда"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се зарежда"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index 7c598229..9e42f71 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"স্বয়ংক্রিয়"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"ওয়েবভিউ প্রয়োগ"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"ওয়েবভিউ প্রয়োগ সেট করুন"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"নির্বাচিত ওয়েবভিউ প্রয়োগটি অক্ষম করা আছে এবং ব্যবহার করার জন্য অবশ্যই সক্ষম করতে হবে, আপনি কি এটিকে সক্ষম করতে চান?"</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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"রঙ সংশোধন"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই বৈশিষ্ট্যটি পরীক্ষামূলক এবং এটি কার্য-সম্পাদনা প্রভাবিত করতে পারে।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - আনুমানিক <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - ACতে সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB এর মাধ্যমে সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> -  বেতার যোগে সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"অজানা"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"চার্জ হচ্ছে"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC তে চার্জ হচ্ছে"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB এর মাধ্যমে চার্জ হচ্ছে"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"তারবিহীনভাবে চার্জ হচ্ছে"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"চার্জ হচ্ছে না"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"চার্জ হচ্ছে না"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"পূর্ণ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 1349a7a..2f81098 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automàtic"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementació de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configura la implementació de WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La implementació de WebView que has triat està desactivada i s\'ha d\'activar per utilitzar-la. Vols activar-la?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Converteix en l\'encriptació de fitxers"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Converteix…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"El fitxer ja està encriptat"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correcció del color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Aquesta funció és experimental i pot afectar el rendiment."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: falten aproximadament <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega per CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega per USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega sense fil"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconegut"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"S\'està carregant"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Càrrega: corr. alt."</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Càrrega per USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Càrrega sense fils"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"No s\'està carregant"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No s\'està carregant"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index beb8f94..f1c9e27 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatický"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementace WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Nastavte implementaci WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Vybraná implementace WebView je zakázána a nelze ji použít. Chcete ji povolit a použít?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Převést na šifrování souborů"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Převést…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Obsah je již na úrovni souborů zašifrován"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekce barev"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkce je experimentální a může mít vliv na výkon."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití ze zásuvky"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití přes USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití bezdrátově"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznámé"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nabíjení z adaptéru"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nabíjení přes USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezdrátové nabíjení"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíjí se"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíjí se"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 3923dbd..90ea69a 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisk"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Konfigurer WebView-implementering"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Den valgte WebView-implementering er deaktiveret og skal aktiveres, før den kan bruges. Vil du aktivere den?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konvertér til filkryptering"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertér…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Allerede filkrypteret"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korriger farver"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funktion er eksperimentel og kan påvirke ydeevnen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet med adapter"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet med USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet med trådløs"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Ukendt"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Opladning med AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Opladning via USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Trådløs opladning"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Oplader ikke"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Oplader ikke"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Fuld"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 4d9d4fb..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>
@@ -109,7 +109,7 @@
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Kurzes Beispiel der Sprachsynthese abspielen"</string>
     <string name="tts_install_data_title" msgid="4264378440508149986">"Sprachdaten installieren"</string>
     <string name="tts_install_data_summary" msgid="5742135732511822589">"Sprachdaten für Sprachsynthese installieren"</string>
-    <string name="tts_engine_security_warning" msgid="8786238102020223650">"Dieses Sprachsynthesemodul kann den gesamten gesprochenen Text erfassen, einschließlich personenbezogener Daten wie Passwörter und Kreditkartennummern. Es ist Teil der App \"<xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>\". Möchten Sie dieses Sprachsynthesemodul aktivieren?"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"Dieses Sprachsynthesemodul kann den gesamten gesprochenen Text erfassen, einschließlich personenbezogener Daten wie Passwörter und Kreditkartennummern. Es ist Teil der App \"<xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>\". Möchtest du dieses Sprachsynthesemodul aktivieren?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Für diese Sprache ist zur Text-in-Sprache-Ausgabe eine aktive Netzwerkverbindung erforderlich."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Dies ist ein Beispiel für Sprachsynthese."</string>
     <string name="tts_status_title" msgid="7268566550242584413">"Status der Standardsprache"</string>
@@ -179,10 +179,10 @@
     <string name="legacy_dhcp_client_summary" msgid="163383566317652040">"DHCP-Client von Lollipop statt des neuen Android-DHCP-Clients verwenden"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Die mobile Datennutzung bleibt auch dann aktiviert, wenn WLAN aktiviert ist. Dies dient einem schnelleren Wechsel zwischen Netzwerken."</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB-Debugging zulassen?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB-Debugging ist nur für Entwicklungszwecke vorgesehen. Damit können Sie Daten zwischen Ihrem Computer und Ihrem Gerät kopieren, Apps auf Ihrem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB-Debugging ist nur für Entwicklungszwecke vorgesehen. Damit kannst du Daten zwischen deinem Computer und deinem Gerät kopieren, Apps auf deinem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zugriff auf USB-Debugging für alle zuvor autorisierten Computer aufheben?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Entwicklungseinstellungen zulassen?"</string>
-    <string name="dev_settings_warning_message" msgid="2298337781139097964">"Diese Einstellungen sind ausschließlich für Entwicklungszwecke geeignet. Sie können Ihr Gerät und die darauf installierten Apps beschädigen oder zu unerwünschtem Verhalten führen."</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"Diese Einstellungen sind ausschließlich für Entwicklungszwecke gedacht. Sie können dein Gerät und die darauf installierten Apps beschädigen oder zu unerwünschtem Verhalten führen."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Apps über USB bestätigen"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Überprüft installierte Apps über ADB/ADT auf schädliches Verhalten"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokales Terminal"</string>
@@ -277,11 +277,12 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisch"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-Implementierung"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-Implementierung festlegen"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Die ausgewählte WebView-Implementierung ist deaktiviert. Um sie nutzen zu können, muss sie aktiviert sein. Möchtest du sie aktivieren?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Zu Dateiverschlüsselung wechseln"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Wechseln…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Dateiverschlüsselung wird bereits verwendet."</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"Zu Dateiverschlüsselung wechseln"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Wechseln Sie von Datenpartitions- zu dateibasierter Verschlüsselung.\n !!Achtung!! Dadurch werden alle Ihre Daten gelöscht.\n Es handelt sich um eine Alphaversion, die möglicherweise nicht korrekt funktioniert.\n Wählen Sie \"Wischen und wechseln…\" aus, um fortzufahren."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Stelle von Datenpartitions- auf dateibasierte Verschlüsselung um.\n !!Achtung!! Dadurch werden alle deine Daten gelöscht.\n Es handelt sich um eine Alphaversion, die möglicherweise nicht korrekt funktioniert.\n Wähle \"Wischen und wechseln…\" aus, um fortzufahren."</string>
     <string name="button_convert_fbe" msgid="5152671181309826405">"Wischen und wechseln…"</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"Farbmodus für Bilder"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"sRGB verwenden"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Farbkorrektur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierbei handelt es sich um eine experimentelle Funktion. Dies kann sich auf die Leistung auswirken."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch etwa <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – bei Stromanschluss voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – über USB voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – bei kabellosem Laden voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Unbekannt"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laden über Netzteil"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laden über USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Kabelloses Laden"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Wird nicht geladen"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wird nicht geladen"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index c3acca7..dddd780 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Διόρθωση χρωμάτων"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Αυτή η λειτουργία είναι πειραματική και ενδεχομένως να επηρεάσει τις επιδόσεις."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση με φορτιστή AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση μέσω USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη ασύρματη φόρτιση"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Άγνωστο"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Φόρτιση"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Φόρτιση με AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Φόρτιση μέσω USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Ασύρματη φόρτιση"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Δεν φορτίζει"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Δεν φορτίζει"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 833fb62..b938ace 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatic"</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">"The chosen WebView implementation is disabled and must be enabled to be used, do you wish to enable it?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convert to file encryption"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convert…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Already file encrypted"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 833fb62..b938ace 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatic"</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">"The chosen WebView implementation is disabled and must be enabled to be used, do you wish to enable it?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convert to file encryption"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convert…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Already file encrypted"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 833fb62..b938ace 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatic"</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">"The chosen WebView implementation is disabled and must be enabled to be used, do you wish to enable it?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convert to file encryption"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convert…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Already file encrypted"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 4d4ab24..ea97ada 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementación de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configurar la implementación de WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La implementación de WebView que elegiste está inhabilitada. Debes habilitarla para poder usarla. ¿Quieres hacerlo?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convertir a encriptación de archivo"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convertir…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Ya está encriptado"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección de color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar el rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: alrededor de <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga por CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga por USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga inalámbrica"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carga en CA"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carga con USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carga inalámbrica"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"No se está cargando."</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se realiza la carga"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 858c1b6..901dc25 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementación de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Establecer implementación de WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La implementación de WebView seleccionada está inhabilitada y debes habilitarla para utilizarla. ¿Quieres hacerlo?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convertir a cifrado de archivo"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convertir…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Ya está cifrado"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección del color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar al rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quedan <xliff:g id="TIME">%2$s</xliff:g> aproximadamente"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería con CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería por USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería con Wi-Fi"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Cargando en CA"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Cargando por USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Cargando de forma inalámbrica"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"No se está cargando"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se está cargando"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index 7f1056c..970812a 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automaatne"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView\' rakendamine"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView\' rakendamise seadistamine"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Valitud WebView\' rakendamisviis on keelatud ja see tuleb kasutamiseks lubada. Kas soovite selle lubada?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Teisendamine failikrüpteeringuga andmeteks"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Teisenda …"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Juba failikrüpteeringuga"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värviparandus"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"See funktsioon on katseline ja võib mõjutada toimivust."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – jäänud on umbes <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (vahelduvvool)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (USB)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (juhtmeta laad.)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Tundmatu"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laad. vahelduvv.-v."</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laadimine USB kaudu"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Juhtmevaba laadimine"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Ei lae"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei lae"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 6405ca8..64a1410 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -277,6 +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 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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kolore-zuzenketa"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> inguru. <xliff:g id="TIME">%2$s</xliff:g> geratzen d(ir)a"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> korrontearen bidez guztiz kargatu arte"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB bidez guztiz kargatu arte"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> haririk gabe guztiz kargatu arte"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Ezezaguna"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzea"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"KA bidez kargatzen"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB bidez kargatzen"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Hari gabe kargatzen"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Ez da kargatzen ari"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ez da kargatzen ari"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index d591426..5380651 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحیح رنگ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"این قابلیت آزمایشی است و ممکن است عملکرد را تحت تأثیر قرار دهد."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً ‏<xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل با جریان متناوب"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"‏<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل از طریق USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل به‌طور بی‌سیم"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ناشناس"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"در حال شارژ شدن"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"شارژ با جریان متناوب"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"‏شارژ از طریق USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"شارژ به صورت بی‌سیم"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"شارژ نمی‌شود"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"شارژ نمی‌شود"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index ce36de3..4b555ac 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automaattinen"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-käyttöönotto"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Määritä WebView-käyttöönotto"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Valittu WebView-käyttöönotto on poistettu käytöstä. Haluatko ottaa sen käyttöön?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Muunna tiedostojen salaukseksi"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Muunna…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Tiedostot on jo salattu."</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värikorjaus"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tämä ominaisuus on kokeellinen ja voi vaikuttaa suorituskykyyn."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (laturilataus)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (USB-lataus)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (WiFi-lataus)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Tuntematon"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laturilataus"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-lataus"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Langaton lataus"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Ei laturissa"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei laturissa"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 3ee0775..96d2e7b 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatique"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Mise en œuvre WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Définir la mise en œuvre WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La mise en œuvre WebView sélectionnée est désactivée. Vous devez l\'activer pour l\'utiliser. Souhaitez-vous l\'activer?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convertir en chiffrement basé sur un fichier"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convertir..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Déjà chiffré par un fichier"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction des couleurs"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut toucher les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> %% – Temps restant : environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (charge complète sur c.a. dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% par USB dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% avec chargeur sans fil dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"En charge (c.a.)"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"En charge par USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"En charge sans fil"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"N\'est pas en charge"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"N\'est pas en charge"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index c0098d2..6dabba8 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatique"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Mise en œuvre WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Définir la mise en œuvre WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"La mise en œuvre WebView sélectionnée est désactivée. Vous devez l\'activer pour l\'utiliser. Souhaitez-vous l\'activer ?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convertir en chiffrement basé sur un fichier"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convertir…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Déjà chiffré via un fichier"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction couleur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g> environ"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% sur secteur dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% via USB dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% sans fil dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"En charge sur secteur"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"En charge via USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"En charge sans fil"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Pas en charge"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Débranchée"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index 0efe805..d3773f6 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementación de WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Definir implementación de WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementación de WebView escollida está desactivada e, para poder usala, debe estar activada. Queres activala?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Converter no encriptado baseado en ficheiros"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Converter..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Xa se encriptou o ficheiro"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función é experimental e pode afectar ao rendemento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - faltan aproximadamente <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga con CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga con USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga co modo sen fíos"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Cargando con CA"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Cargando por USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Cargando sen fíos"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Non se está cargando"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non está cargando"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 2a0ff45..9e2ec7e 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"રંગ સુધારણા"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"આ સુવિધા પ્રાયોગિક છે અને કામગીરી પર અસર કરી શકે છે."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - આશરે <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"સંપૂર્ણ થવામાં <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>, AC પર પૂર્ણ ચાર્જ થયાંને <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>, USB પર પૂર્ણ ચાર્જ થયાંને <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> વાયરલેસ દ્વારા પૂર્ણ થાય ત્યાં સુધી"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"અજાણ્યું"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ચાર્જ થઈ રહ્યું છે"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC પર ચાર્જિંગ"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB થી ચાર્જિંગ"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"વાયરલેસથી ચાર્જિંગ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ચાર્જ થઈ રહ્યું નથી"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ચાર્જ થઈ રહ્યું નથી"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 5224c38..b6b8eac 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यह सुविधा प्रायोगिक है और निष्पादन को प्रभावित कर सकती है."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी होने तक"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC पर पूरी होने तक"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB पर पूरी होने तक"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेस से पूरी होने तक"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हो रही है"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC से चार्ज हो रही"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB पर चार्ज हो रही"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"वायरलेस रूप से चार्ज हो रही"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज नहीं हो रही है"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज नहीं हो रही है"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 0a46b27..69b71fe 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatska"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementacija WebViewa"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Postavi implementaciju WebViewa"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Odabrana implementacija WebViewa onemogućena je i morate je omogućiti da biste je mogli upotrebljavati. Želite li je omogućiti?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Pretvori u enkripciju datoteka"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Pretvori…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Enkripcija datoteka već je izvršena"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boje"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova je značajka eksperimentalna i može utjecati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – još približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti strujnim napajanjem"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti putem USB-a"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti bežičnim putem"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Punjenje punjačem"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje putem USB-a"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 3559f1e..26d65fb 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatikus"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-megvalósítás"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-megvalósítás beállítása"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A kiválasztott WebView-megvalósítás le van tiltva, a használathoz viszont engedélyezni kell. Szeretné engedélyezni?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konvertálás fájlalapú titkosításra"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertálás…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Már fájlalapú titkosítást használ"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Színkorrekció"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ez egy kísérleti funkció, és hatással lehet a teljesítményre."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – kb. <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes töltöttség eléréséig"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig hálózatról"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig USB-ről"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a feltöltésig vezeték nélkül"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Ismeretlen"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Töltés"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Hálózati töltés"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-s töltés"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Nem vezetékes töltés"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nem tölt"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nem töltődik"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Feltöltve"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index fb401f0..0caa981 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Գունային կարգաբերում"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Սա փորձնական գործառույթ է և կարող է ազդել աշխատանքի վրա:"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնաց մոտավորապես <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը հոսանքից"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը USB-ով"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը անլար ցանցից"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Անհայտ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Լիցքավորում"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Լիցքավորում AC-ով"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Լիցքավորում USB-ով"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Անլար լիցքավորում"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Չի լիցքավորվում"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Չի լիցքավորվում"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 1262512..7aba923 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Otomatis"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Penerapan WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Setel penerapan WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Implementasi WebView yang dipilih telah dinonaktifkan, dan harus diaktifkan agar dapat digunakan. Ingin mengaktifkannya?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konversi ke enkripsi file"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konversi..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Sudah dienkripsi berbasis file"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Koreksi warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Fitur ini bersifat eksperimental dan dapat memengaruhi kinerja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira tersisa. <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh pada AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh melalui USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh dari nirkabel"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Mengisi daya pada AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Isi daya lewat USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Isi daya nirkabel"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengisi daya"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengisi daya"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 3e53e94..a534db6 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Sjálfvirkt"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Innleiðing WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Stilla innleiðingu WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Slökkt er á valinni innleiðingu WebView. Kveikja þarf á henni til að hægt sé að nota hana. Viltu gera það?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Umbreyta í dulkóðun skráa"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Umbreyta…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Þegar dulkóðað á grundvelli skráa"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Litaleiðrétting"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Þessi eiginleiki er á tilraunastigi og getur haft áhrif á frammistöðu."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – u.þ.b. <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu með hleðslutæki"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu í gegnum USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu þráðlaust"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Óþekkt"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Hleðslutæki tengt"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Hleður um USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Hleður þráðlaust"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Ekki í hleðslu"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ekki í hleðslu"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 2d98a74..eedfa33 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatico"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementazione di WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Imposta l\'implementazione di WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"L\'implementazione di WebView selezionata non è attiva e deve essere attivata per poterla utilizzare. Vuoi attivarla?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Converti in crittografia basata su file"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Converti..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Crittografia su base file già eseguita"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correzione del colore"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g> circa"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lla carica completa con wireless"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Sconosciuta"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"In carica tramite CA"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"In carica tramite USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"In carica, wireless"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Non in carica"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non in carica"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 54099c7..eb26eaf 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -247,8 +247,8 @@
     <string name="force_allow_on_external_summary" msgid="3191952505860343233">"מאפשר כתיבה של כל אפליקציה באחסון חיצוני, ללא התחשבות בערכי המניפסט"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"אלץ יכולת קביעת גודל של הפעילויות"</string>
     <string name="force_resizable_activities_summary" msgid="4508217476997182216">"מאפשר יכולת קביעת גודל של כל הפעילויות לריבוי חלונות, ללא קשר לערך המניפסט."</string>
-    <string name="enable_freeform_support" msgid="1461893351278940416">"הפעל חלונות בצורה חופשית"</string>
-    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"מפעיל תמיכה בתכונה הניסיונית של חלונות בצורה חופשית."</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"הפעל את האפשרות לשנות את הגודל והמיקום של החלונות"</string>
+    <string name="enable_freeform_support_summary" msgid="2252563497485436534">"מפעיל תמיכה בתכונה הניסיונית של שינוי הגודל והמיקום של החלונות."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"סיסמת גיבוי מקומי"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"גיבויים מלאים בשולחן העבודה אינם מוגנים כעת"</string>
     <string name="local_backup_password_summary_change" msgid="2731163425081172638">"גע כדי לשנות או להסיר את הסיסמה עבור גיבויים מלאים בשולחן העבודה"</string>
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"תיקון צבע"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"תכונה זו היא ניסיונית ועשויה להשפיע על הביצועים."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> בקירוב עד לסיום"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>‏ - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> ‏- <xliff:g id="TIME">%2$s</xliff:g> עד למילוי"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> ‏- <xliff:g id="TIME">%2$s</xliff:g> עד למילוי בזרם חילופין"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"‏<xliff:g id="LEVEL">%1$s</xliff:g> ‏- <xliff:g id="TIME">%2$s</xliff:g> עד למילוי ב-USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> ‏- <xliff:g id="TIME">%2$s</xliff:g> עד למילוי בטעינה אלחוטית"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"לא ידוע"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"טוען"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"טוען בזרם חילופין"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"‏טוען ב-USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"טוען באופן אלחוטי"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"לא בטעינה"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"לא טוען"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 7e45fb2..dfa7456 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,20 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色補正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"この機能は試験運用機能であり、パフォーマンスに影響することがあります。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約<xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(AC)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(USB)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(ワイヤレス)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ACで充電しています"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USBで充電しています"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"無線で充電しています"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"充電していません"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"充電していません"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for battery_info_status_full (2824614753861462808) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index a8f25c6..0f0428f 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ფერის კორექცია"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ეს ფუნქცია საცდელია და შეიძლება გავლენა იქონიოს შესრულებაზე."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"დაახლ. <xliff:g id="LEVEL">%1$s</xliff:g> დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> სრულ დატენვამდე"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ელკვებით სრულ დატენვამდე"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB-თი სრულ დატენვამდე"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> უსადენოდან სრულ დატენვამდე"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"უცნობი"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"იტენება"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"დატენვა ელკვებაზე"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"დატენვა USB-ზე"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"დატენვა უსადენოდ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"არ იტენება"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"არ იტენება"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index 300aaa3..2f2ffbc 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Aвтоматты"</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">"Таңдалған веб-көріністі енгізу өшірілген және пайдалану үшін оны қосу керек. Оны қосу керек пе?"</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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсті түзету"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бұл мүмкіндік эксперименттік болып табылады және өнімділікке әсер етуі мүмкін."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - айнымалы токпен толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB арқылы толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - сымсыз толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Белгісіз"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядталуда"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Айнымалы токпен зар."</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB арқылы зарядтау"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Сымсыз зарядтау"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Зарядталу орындалып жатқан жоқ"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Зарядталып тұрған жоқ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index a414668..6feb93d 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ការ​កែ​ពណ៌"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"លក្ខណៈ​នេះ​គឺ​ជា​ការ​ពិសោធន៍ ហើយ​អាច​ប៉ះពាល់​ការ​អនុវត្ត។"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅ​សល់​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូត​ដល់​ពេញ"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូត​ដល់ពេញ​រចន្ត​ឆ្លាស់"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូត​ដល់​ពេញ​តាមយូអេសប៊ី"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូត​ដល់​ពេញ​ពី​ឥតខ្សែ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"មិន​ស្គាល់"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូល​ថ្ម"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"បញ្ចូលថ្មតាម AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"បញ្ចូលថ្មតាមយូអេសប៊ី"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"បញ្ចូលថ្មដោយ​​ឥតខ្សែ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"មិនកំពុង​បញ្ចូល​ថ្ម"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"មិន​បញ្ចូលថ្ម"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index 50e5955..948c665315 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ಬಣ್ಣದ ತಿದ್ದುಪಡಿ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ಇದು ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಕಾರ್ಯಕ್ಷಮತೆ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"ಸುಮಾರು <xliff:g id="LEVEL">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC ನಲ್ಲಿ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ಮೂಲಕ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ವೈರ್‌‌ಲೆಸ್‌ನಿಂದ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ಅಜ್ಞಾತ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ನಲ್ಲಿ ಚಾರ್ಜ್‌"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ಮೂಲಕ ಚಾರ್ಜ್‌"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ನಿಸ್ತಂತುವಾಗಿ ಚಾರ್ಜ್‌"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ಚಾರ್ಜ್‌ ಆಗುತ್ತಿಲ್ಲ"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index c23a8a7..ae82263 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"색보정"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"실험실 기능이며 성능에 영향을 줄 수 있습니다."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 대략 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(AC 전원)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(USB)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(무선)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"알 수 없음"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"충전 중"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"충전 중(AC 전원)"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"충전 중(USB)"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"충전 중(무선)"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"충전 안함"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"충전 안함"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 84bfe94f..fcd7b8f 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсүн тууралоо"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, иштин майнаптуулугуна таасир этиши мүмкүн."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - болжол менен <xliff:g id="TIME">%2$s</xliff:g> саат калды"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> толгончо"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC аркылуу толгончо"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB аркылуу толгончо"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> зымсыз кубаттоо аркылуу толгончо"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Белгисиз"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Кубатталууда"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ӨА кубатталууда"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB\'ден кубатталууда"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Зымсыз кубатталууда"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Кубат алган жок"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Кубатталган жок"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index 4b5359a..c29b9ab 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ການ​ປັບ​ແຕ່ງ​ສີ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"​ຄຸນ​ສົມ​ບັດ​ນີ້​ກຳ​ລັງ​ຢູ່​ໃນ​ການ​ທົດ​ລອງ​ແລະ​ອາດ​ມີ​ຜົນ​ຕໍ່​ປະ​ສິດ​ທິ​ພາບ."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ​ເຫຼືອປະ​ມານ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງ​ຈະ​ເຕັມ"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ​ຈຶ່ງ​ຈະ​ເຕັມ​ໂດຍສາກ​ດ້ວຍ​ໄຟ AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງ​ຈະ​ເຕັມ​ໂດຍສາກ​ດ້ວຍ USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ​ຈຶ່ງ​ຈະ​ເຕັມ​ໂດຍ​ສາກ​ແບບ​ໄຮ້​ສາຍ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ບໍ່ຮູ້ຈັກ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ກຳລັງສາກໄຟ"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ກຳ​​ລັງ​ສາກ​ຜ່ານ​ໝໍ້​ໄຟ"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"ກຳ​ລັງ​ສາກ​ຜ່ານ USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ກຳ​ລັງ​ສາກ​ໄຮ້​ສາຍ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ບໍ່ໄດ້ສາກໄຟ"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ບໍ່ໄດ້ສາກໄຟ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 6b21041..a75c24e 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatinė"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"„WebView“ diegimas"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"„WebView“ diegimo nustatymas"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Pasirinktas „WebView“ diegimas išjungtas ir jį būtina įgalinti, kad būtų galima naudoti. Ar norite jį įgalinti?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konvertuoti į failų šifruotę"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertuoti…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Jau konvertuota į failų šifruotę"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Spalvų taisymas"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ši funkcija yra eksperimentinė ir ji gali turėti įtakos našumui."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo naud. kint. sr."</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo naudojant USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo belaid. ryš."</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Nežinomas"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Įkr. naud. kint. sr."</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Įkraunama naud. USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Įkraunama be laidų"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nekraunama"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nekraunama"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 0652b05..23aa537 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automātiski"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ieviešana"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Iestatīt WebView ieviešanu"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Izvēlētā WebView ieviešana ir atspējota, un tā ir jāiespējo, lai to varētu izmantot. Vai vēlaties to iespējot?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Pārvērst par failu šifrējumu"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Pārvērst…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Jau šifrēts failu līmenī"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Krāsu korekcija"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Šī funkcija ir eksperimentāla un var ietekmēt veiktspēju."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> — aptuvenais atlikušais laiks: <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai maiņstrāvas uzlādei"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai USB uzlādei"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai bezvadu uzlādei"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Nezināms"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Maiņstrāvas uzlāde"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB uzlāde"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezvadu uzlāde"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nenotiek uzlāde"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenotiek uzlāde"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index b588c2c..32d276e 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција на боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостанува приближно <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна на AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна преку USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна, безжично"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Полнење на струја"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Полнење преку УСБ"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Безжично полнење"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Не се полни"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се полни"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Целосна"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 2457847..9684b7b 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"വർണ്ണം ക്രമീകരിക്കൽ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ഈ ഫീച്ചർ പരീക്ഷണാത്മകമായതിനാൽ പ്രകടനത്തെ ബാധിച്ചേക്കാം."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC-യിൽ പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - വയർലെസ് വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"അജ്ഞാതം"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ്ജുചെയ്യുന്നു"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC-യിൽ ചാർജ്ജുചെയ്യുന്നു"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-യിലൂടെ ചാർജ്ജുചെയ്യുന്നു"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"വയർലെസ്സ് കണക്ഷനിലൂടെ ചാർജ്ജുചെയ്യുന്നു"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index 622c13f..a3f9dfa 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Өнгө тохируулах"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Энэ функц туршилтынх бөгөөд ажиллагаанд нөлөөлж болзошгүй."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"АС-р дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"USB-р дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"утасгүй цэнэглэгчээр дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Тодорхойгүй"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Цэнэглэж байна"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC-р цэнэглэж байна"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-р цэнэглэж байна"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Кабльгүйгээр цэнэглэж байна"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Цэнэглэхгүй байна"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Цэнэглэхгүй байна"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index ed57fb7..804fab0 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"स्वयंचलित"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"वेबदृश्य अंमलबजावणी"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"वेबदृश्य अंमलबजावणी सेट करा"</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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधारणा"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"हे वैशिष्‍ट्य प्रायोगिक आहे आणि कदाचित कार्यप्रदर्शन प्रभावित करू शकते."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - अंदाजे. <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण होण्यात"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC वरून पूर्ण होण्यात"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB वरून पूर्ण होण्यात"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेसवरून पूर्ण होण्यात"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज होत आहे"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC वर चार्ज करीत आहे"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB वरून चार्ज करीत आहे"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"वायरलेस वरून चार्ज करीत आहे"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज होत नाही"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज होत नाही"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 5f27232..7020409 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatik"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Pelaksanaan WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Tetapkan pelaksanaan WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Pelaksanaan WebView pilihan telah dilumpuhkan dan mesti didayakan untuk digunakan, adakah anda mahu mendayakannya?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Tukar kepada penyulitan fail"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Tukar..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Sudah disulitkan fail"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pembetulan warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ciri ini adalah percubaan dan boleh menjejaskan prestasi."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira. <xliff:g id="TIME">%2$s</xliff:g> yang tinggal"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh di AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh melalui USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh dari wayarles"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Mengecas pada AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Mengecas melalui USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Mengecas tanpa wayar"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengecas"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengecas"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index 0a86cdb..e40da23 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"အရောင်ပြင်ဆင်မှု"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ဒီအင်္ဂါရပ်မှာ စမ်းသပ်မှု ဖြစ်၍ လုပ်ကိုင်မှုကို အကျိုးသက်ရောက်နိုင်သည်။"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ခန့်မှန်းခြေ။ <xliff:g id="TIME">%2$s</xliff:g> ကျန်ရှိနေ"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> အပြည့်အထိ"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> လျှပ်စစ်ဖြင့် အပြည့်အထိ"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ဖြင့် အပြည့်အထိ"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ကြိုးမဲ့ဖြင့် အပြည့်အထိ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"အကြောင်းအရာ မသိရှိ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"အားသွင်းနေပါသည်"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"လျှပ်စစ်ဖြင့် အားသွင်းနေ"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USBဖြင့် အားသွင်းနေ"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ကြိုးမဲ့ အားသွင်းနေ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"အားသွင်းမနေပါ"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"အားသွင်းမနေပါ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 99ee44c..e39cf30 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisk"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Angi WebView-implementering"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Den valgte implementeringen av nettvisningen er slått av – den må slås på for å brukes. Vil du slå den på?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konvertér til kryptert fil"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertér …"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Allerede kryptert og lagret som fil"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Fargekorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funksjonen er eksperimentell og kan påvirke ytelsen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> igjen"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> –  fulladet om <xliff:g id="TIME">%2$s</xliff:g> med vekselstrøm"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> via USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> via trådløs lading"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Ukjent"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Lader via strømuttak"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Lader via USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Lader trådløst"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Lader ikke"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Lader ikke"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index a109197..b8beecf 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रङ्ग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यो सुविधा प्रयोगात्मक छ र प्रदर्शनमा असर गर्न सक्छ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग। <xliff:g id="TIME">%2$s</xliff:g> बायाँ"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण नभए सम्म"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC मा पूर्ण नभए सम्म"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB मा पूर्ण नभए सम्म"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेसबाट पूर्ण नभए सम्म"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हुँदै"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC मा चार्ज गर्दै"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB मा चार्ज गर्दै"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"बिना तार चार्ज गर्दै"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज भइरहेको छैन"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज हुँदै छैन"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 1dd477d..4873ac3 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatisch"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementatie"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-implementatie instellen"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"De gekozen WebView-implementatie is uitgeschakeld en moet worden ingeschakeld voor gebruik. Wil je deze inschakelen?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Converteren naar versleuteling op basis van bestanden"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Converteren…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Al versleuteld op basis van bestanden"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurcorrectie"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Deze functie is experimenteel en kan invloed hebben op de prestaties."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ca. <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via wisselstroom"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via draadloos"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Opladen via netvoeding"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Opladen via USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Draadloos opladen"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Wordt niet opgeladen"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wordt niet opgeladen"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index 85f9ffb..61f187d 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ਰੰਗ ਸੰਸ਼ੋਧਨ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਾਤਮਿਕ ਹੈ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਤੇ ਅਸਰ ਪਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC ਤੇ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ਤੇ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਵਾਇਰਲੈਸ ਤੋਂ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜਿੰਗ"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ਤੇ ਚਾਰਜਿੰਗ"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ਤੇ ਚਾਰਜਿੰਗ"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ਵਾਇਰਲੈਸ ਤੌਰ ਤੇ ਚਾਰਜਿੰਗ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 9f7c022..9e0abfa 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatycznie"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementacja WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Ustaw implementację WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Wybrana implementacja WebView jest wyłączona. Aby jej używać, musisz ją włączyć. Chcesz to zrobić?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Przekształć na szyfrowanie plików"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Przekształć…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Pliki są już zaszyfrowane"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcja kolorów"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To jest funkcja eksperymentalna i może wpływać na działanie urządzenia."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało ok. <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania z gniazdka"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania przez USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania bezprzewodowo"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Nieznane"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Ładowanie zasilaczem"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Ładowanie przez USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Ład. bezprzewodowe"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nie podłączony"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nie podłączony"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 98a3121..db6b326 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementação do WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configurar implementação do WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementação do WebView escolhida está desativada e deve ser ativada para ser usada. Deseja ativá-la?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Converter para criptografia de arquivos"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Converter..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Já criptografado com base em arquivos"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir em CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir via USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir sem fio"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carregamento CA"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carregamento via USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carregamento sem fio"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 0cbe5e4..2f25ae2 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementação WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Definir implementação WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementação WebView escolhida foi desativada e tem de ser ativada para poder ser utilizada. Pretende ativá-la?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Converter para a encriptação de ficheiros"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Converter..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Os ficheiros já estão encriptados"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta funcionalidade é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) aprox. <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa através de CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa através de USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até ficar compl. por rede s/ fios"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"A carregar por CA"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"A carregar por USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"A carregar sem fios"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Não está a carregar"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está a carregar"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 98a3121..db6b326 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automático"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementação do WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Configurar implementação do WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"A implementação do WebView escolhida está desativada e deve ser ativada para ser usada. Deseja ativá-la?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Converter para criptografia de arquivos"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Converter..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Já criptografado com base em arquivos"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir em CA"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir via USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir sem fio"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carregamento CA"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carregamento via USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carregamento sem fio"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 00ff92b..e6a45a7 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automat"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementare WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Setați implementarea WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Implementarea WebView aleasă este dezactivată. Pentru a fi folosită, trebuie să fie activată. Doriți să o activați?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Faceți conversia la criptarea bazată pe sistemul de fișiere"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convertiți…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Criptarea bazată pe sistemul de fișiere este finalizată"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corecția culorii"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Această funcție este experimentală și poate afecta performanțele."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă la c.a."</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă prin USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă wireless"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Necunoscut"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Se încarcă la C.A."</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Se încarcă prin USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Se încarcă fără fir"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nu se încarcă"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 9a3a7e6..2bb3fdb3 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Коррекция цвета"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Это экспериментальная функция, она может снизить производительность устройства."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось около <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (от сети)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (через USB)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (беспроводная)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Идет зарядка"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зарядка от сети"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зарядка через USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Беспроводная зарядка"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряжается"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряжается"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index 083dd05..bd9426c 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"වර්ණ නිවැරදි කිරීම"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"මෙම විශේෂාංගය පරීක්ෂණාත්මක සහ ඇතැම් විට ක්‍රියාකාරිත්වයට බලපෑ හැක."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආසන්න <xliff:g id="TIME">%2$s</xliff:g> වම"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"AC හි <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"USB හරහ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"රේඩියෝව වෙතින් <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පූර්ණ වන තෙක්"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"නොදනී"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ආරෝපණය වෙමින්"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC හි ආරෝපණය වෙමින්"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB හරහා ආරෝපණය වෙමින්"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"රැහැන් රහිතව ආරෝපණය වෙමින්"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ආරෝපණය නොවේ"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ආරෝපණය නොවෙමින්"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index e12f435..8df02ea 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatický"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Implementácia komponenta WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Nastavenie implementácie komponenta WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Zvolená implementácia technológie WebView je zakázaná. Ak ju chcete použiť, musíte ju najprv povoliť. Chcete ju povoliť?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konvertovať na šifrovanie súborov"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertovať…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Súbory sú už šifrované"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Úprava farieb"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkcia je experimentálna a môže mať vplyv na výkonnosť."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostáva približne <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia zo zásuvky"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia cez USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia bezdrôtovo"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznáme"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjanie"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nabíjanie zo zásuvky"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nabíjanie cez USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezdrôtové nabíjanie"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíja sa"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 1f66583..57495e6 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Samodejno"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Izvedba spletnega pogleda"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Nastavitev izvedbe spletnega pogleda"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Izbrana izvedba spletnega pogleda je onemogočena in jo morate omogočiti, če jo želite uporabljati. Ali jo želite omogočiti?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Preklop na šifriranje podatkov"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Preklop …"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Šifriranje podatkov je že uveljavljeno"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Popravljanje barv"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To je preskusna funkcija in lahko vpliva na učinkovitost delovanja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek napajalnika"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek USB-ja"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek brezž. pol."</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznano"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Polnj. prek iz. toka"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Polnj. prek USB-ja"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Brezžično polnjenje"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Se ne polni"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Se ne polni"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index 7f4d6a8..1835b39 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatike"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Zbatimi i WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Cakto zbatimin e WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Është çaktivizuar zbatimi i zgjedhur i WebView dhe duhet të aktivizohet për t\'u përdorur, dëshiron ta aktivizosh?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konverto në enkriptimin e skedarit"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konverto..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Enkriptimi i skedarit është kryer tashmë"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korrigjimi i ngjyrës"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ky funksion është eksperimental dhe mund të ndikojë në veprimtari."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - afërsisht <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të jetë e plotë"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet në AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet me USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet nga lidhja pa tel"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"I panjohur"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Po ngarkohet"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Po ngarkohet në AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Po ngarkohet me USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Po ngarkohet me valë"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Nuk po ngarkohet"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nuk po ngarkohet"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index ab96afd..c39682a 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ова функција је експериментална и може да утиче на перформансе."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостало око <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни пуњачем"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни преко USB-а"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни бежично"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Пуњење"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Пуњење преко пуњача"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Пуњење преко USB-а"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Бежично пуњење"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Не пуни се"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не пуни се"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index f8901c9..1bdf6b2 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatiskt"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-implementering"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Ange WebView-implementering"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Den valda WebView-implementeringen har inaktiverats och måste aktiveras om du ska kunna använda den. Vill du aktivera den?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Konvertera till filkryptering"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Konvertera …"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Filkryptering används redan"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Färgkorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Den här funktionen är experimentell och kan påverka prestandan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via laddare"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via trådlös laddning"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Okänd"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laddas via adapter"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laddas via USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Laddas trådlöst"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Laddar inte"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laddar inte"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 8a33946..9cf0db7 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Otomatiki"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Utekelezaji wa WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Weka utekelezaji wa WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Kipengee ulichochagua cha utekelezaji wa WebView kimezimwa. Ni lazima ukiwashe ili kitumike. Ungependa kukiwasha?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Badilisha kuwa usimbaji fiche wa faili"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Badilisha..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Tayari faili imesimbwa kwa njia fiche"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Usahihishaji wa rangi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Kipengele hiki ni cha majaribio na huenda kikaathiri utendaji."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takriban <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa kutumia AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>%% - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa kutumia USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa isiyotumia waya"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Haijulikani"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Inachaji kupitia AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Inachaji kupitia USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Inachaji bila kutumia waya"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Haichaji"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Haichaji"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index d386039..c21db5b 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"வண்ணத்திருத்தம்"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"தோராயம்: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> உள்ளது"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"முழு சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"முழு AC சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"முழு USB சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"முழு வயர்லெஸ் சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"அறியப்படாத"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஏற்றப்படுகிறது"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC மூலம் சார்ஜாகிறது"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB மூலம் சார்ஜாகிறது"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"வயர்லெஸில் சார்ஜாகிறது"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"சார்ஜ் செய்யப்படவில்லை"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index 80b84f0..04f0ca0 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"స్వయంచాలకం"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"వెబ్ వీక్షణ అమలు"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"వెబ్ వీక్షణ అమలుని సెట్ చేయండి"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"ఎంచుకున్న వెబ్ వీక్షణ అమలు నిలిపివేయబడింది, కానీ ఉపయోగించడానికి తప్పనిసరిగా ప్రారంభించాల్సి ఉంటుంది, మీరు దీన్ని ప్రారంభించాలనుకుంటున్నారా?"</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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"రంగు సవరణ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - సుమారు <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - ACలో పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB ద్వారా పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - వైర్‌లెస్ నుండి పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"తెలియదు"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ఛార్జ్ అవుతోంది"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ACలో ఛార్జ్ అవుతోంది"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ద్వారా ఛార్జ్ అవుతోంది"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"వైర్‌లెస్‌ ద్వారా ఛార్జ్ అవుతోంది"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ఛార్జ్ కావడం లేదు"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ఛార్జ్ కావడం లేదు"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b17b516..acde81e 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"การแก้สี"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"คุณลักษณะนี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็ม"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่าน AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่าน USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่านระบบไร้สาย"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ไม่ทราบ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"กำลังชาร์จไฟ AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"กำลังชาร์จผ่าน USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"กำลังชาร์จแบบไร้สาย"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ไม่ได้ชาร์จ"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ไม่ได้ชาร์จ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index d0e7f87..7e856e85 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Awtomatiko"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Pagpapatupad sa WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Itakda ang pagpapatupad sa WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Naka-disable ang napiling pagpapatupad sa WebView, at dapat itong i-enable upang magamit, gusto mo ba itong i-enable?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"I-convert at gawing pag-encrypt ng file"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"I-convert..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Na-encrypt na ang file"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pagtatama ng kulay"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ang feature na ito ay pinag-eeksperimentuhan at maaaring makaapekto sa pagganap."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit kumulang <xliff:g id="TIME">%2$s</xliff:g> ang natitira"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno sa AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno sa USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno mula sa wireless"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Hindi Kilala"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nagcha-charge sa AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nagcha-charge sa USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Wireless nag-charge"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Hindi nagcha-charge"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hindi nagkakarga"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index e6ddcdd..8577f7d 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Otomatik"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView kullanımı"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView kullanımını ayarla"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Seçilen WebView uygulama şekli devre dışı. Bu uygulama şeklinin kullanılabilmesi için etkinleştirilmesi gerekir. Etkinleştirmek istiyor musunuz?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Dosya şifrelemeye dönüştür"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Dönüştür…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Dosya şifreleme zaten uygulandı"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Renk düzeltme"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu özellik deneyseldir ve performansı etkileyebilir."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - prize takılı, tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB üzerinden şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - kablosuzdan tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Bilinmiyor"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ile şarj oluyor"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ile şarj oluyor"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Kablosuz şarj oluyor"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Şarj olmuyor"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Şarj etmiyor"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 2448b23..3e89cce 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекція кольору"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Це експериментальна функція. Вона може вплинути на продуктивність."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилось близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження з розетки"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження через USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного з бездротового зарядження"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Невідомо"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядж-ся"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Заряджання з розетки"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Заряджання через USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Заряджання без дроту"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряджається"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряджається"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index e9fe7e4..a565ab7 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"رنگ کی اصلاح"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"یہ خصوصیت تجرباتی ہے اور اس کی وجہ سے کاکردگی متاثر ہو سکتی ہے۔"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g>‎ - تقریبا <xliff:g id="TIME">%2$s</xliff:g> باقی"</string>
+    <string name="power_charging" msgid="1779532561355864267">"‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>‎"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>‎ پورا ہونے تک"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC‎ پر پورا ہونے تک"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB‎ پر پورا ہونے تک"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>‎ وائرلیس سے پورا ہونے تک"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"نامعلوم"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"چارج ہو رہا ہے"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"‏AC پر چارج ہو رہی ہے"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"‏‫USB پر چارج ہورہی ہے"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"وائرلیس چارجنگ"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"چارج نہیں ہو رہا ہے"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"چارج نہیں ہو رہا ہے"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index e53336b..246287a 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Avtomatik"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView ta’minotchisi"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView ta’minotchisini sozlash"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Tanlangan WebView ta’minotchisi o‘chirilgan va foydalanish uchun yoqilishi zarur. Yoqilsinmi?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Faylli shifrga o‘girish"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"O‘girish…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Fayl allaqachon shifrlangan"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rangni tuzatish"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, to‘lguncha"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, o‘zgaruvchan tok orqali to‘lguncha"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, USB orqali to‘lguncha"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, simsiz quvvatlash orqali to‘lguncha"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Noma’lum"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Quvvat olmoqda (AC)"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Quvvat olmoqda (USB)"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Simsiz quvvat olmoqda"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Quvvatlantirilmayapti"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Quvvatlanmayapti"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 193f066..f07c8a0 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Tự động"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Triển khai WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Đặt triển khai WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Triển khai WebView đã chọn bị vô hiệu hóa và bạn phải bật để sử dụng tính năng này. Bạn có muốn bật tính năng này không?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Chuyển đổi sang mã hóa tệp"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Chuyển đổi..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Đã mã hóa tệp"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Sửa màu"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tính năng này là tính năng thử nghiệm và có thể ảnh hưởng đến hoạt động."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy khi cắm vào nguồn AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy qua USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy từ không dây"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Không xác định"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Sạc trên AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Sạc qua USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Sạc không dây"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Hiện không sạc"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hiện không sạc"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index de8996e..5c4f733 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -277,6 +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 实现已停用,您必须先启用 WebView 实现才能加以使用。要启用该 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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"此功能为实验性功能,可能会影响性能。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用大约<xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(交流电充电)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(USB充电)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(无线充电)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"正在充电"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在通过交流电源充电"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在通过USB充电"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在无线充电"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"未在充电"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未在充电"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 9a86f3a..952b198 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -277,6 +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="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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會影響效能。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (透過插頭充電)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (透過 USB 充電)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (無線充電)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在透過 AC 充電"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在透過 USB 充電"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在透過無線方式充電"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未開始充電"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 3ab60f5..f66f093 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -277,6 +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 實作已停用,您必須先啟用 WebView 實作才能加以使用。要啟用該 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>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會對效能造成影響。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大約還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (AC)"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (USB)"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (無線充電)"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在透過 AC 變壓器充電"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在透過 USB 充電"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在透過無線方式充電"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"非充電中"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index bf3addf..f42abbc 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -277,6 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Okuzenzakalelayo"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"Ukufakwa ke-WebView"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Sesba ukufakwa kwe-WebView"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Ukusetshenziswa kwe-WebView okukhethiwe kukhutshaziwe, futhi kuzomele kunikwe amandla ukuze kusetshenziswe, ingabe ufisa ukukunika amandla?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Phendulisela ekubethelweni kwefayela"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Iyaphendulela..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Sekuvele kubethelwe ngefayela"</string>
@@ -293,4 +294,18 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ukulungiswa kombala"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Lesi sici esesilingo futhi singathinta ukusebenza."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - isilinganiso esingu-<xliff:g id="TIME">%2$s</xliff:g> esisele"</string>
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale"</string>
+    <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale ku-AC"</string>
+    <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale ngaphezulu kwe-USB"</string>
+    <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale kusukela kokungenantambo"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"Akwaziwa"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string>
+    <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Iyashaja ku-AC"</string>
+    <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Iyashaja ngaphezulu kwe-USB"</string>
+    <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Iyashaja ngaphandle kwentambo"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Ayishaji"</string>
+    <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ayishaji"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index f6caaa9..d69250b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -16,14 +16,18 @@
 
 package com.android.settingslib;
 
+import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.IPackageManager;
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.text.Spanned;
 import android.text.SpannableStringBuilder;
@@ -124,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;
+                    }
                 }
             }
         }
@@ -147,30 +153,165 @@
         return enforcedAdmin;
     }
 
+    public static EnforcedAdmin checkIfUninstallBlocked(Context context,
+            String packageName, int userId) {
+        EnforcedAdmin allAppsControlDisallowedAdmin = checkIfRestrictionEnforced(context,
+                UserManager.DISALLOW_APPS_CONTROL, userId);
+        if (allAppsControlDisallowedAdmin != null) {
+            return allAppsControlDisallowedAdmin;
+        }
+        EnforcedAdmin allAppsUninstallDisallowedAdmin = checkIfRestrictionEnforced(context,
+                UserManager.DISALLOW_UNINSTALL_APPS, userId);
+        if (allAppsUninstallDisallowedAdmin != null) {
+            return allAppsUninstallDisallowedAdmin;
+        }
+        IPackageManager ipm = AppGlobals.getPackageManager();
+        try {
+            if (ipm.getBlockUninstallForUser(packageName, userId)) {
+                DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                        Context.DEVICE_POLICY_SERVICE);
+                ComponentName admin = dpm.getProfileOwner();
+                if (admin == null) {
+                    admin = dpm.getDeviceOwnerComponentOnCallingUser();
+                }
+                return new EnforcedAdmin(admin, UserHandle.myUserId());
+            }
+        } catch (RemoteException e) {
+            // Nothing to do
+        }
+        return null;
+    }
+
+    /**
+     * Check if account management for a specific type of account is disabled by admin.
+     * Only a profile or device owner can disable account management. So, we check if account
+     * management is disabled and return profile or device owner on the calling user.
+     *
+     * @return EnforcedAdmin Object containing the enforced admin component and admin user details,
+     * or {@code null} if the account management is not disabled.
+     */
+    public static EnforcedAdmin checkIfAccountManagementDisabled(Context context,
+            String accountType) {
+        if (accountType == null) {
+            return null;
+        }
+        DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        boolean isAccountTypeDisabled = false;
+        String[] disabledTypes = dpm.getAccountTypesWithManagementDisabled();
+        for (String type : disabledTypes) {
+            if (accountType.equals(type)) {
+                isAccountTypeDisabled = true;
+                break;
+            }
+        }
+        if (!isAccountTypeDisabled) {
+            return null;
+        }
+        return getProfileOrDeviceOwnerOnCallingUser(context);
+    }
+
+    /**
+     * Checks if {@link android.app.admin.DevicePolicyManager#setAutoTimeRequired} is enforced
+     * on the device.
+     *
+     * @return EnforcedAdmin Object containing the device owner component and
+     * userId the device owner is running as, or {@code null} setAutoTimeRequired is not enforced.
+     */
+    public static EnforcedAdmin checkIfAutoTimeRequired(Context context) {
+        DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        if (dpm.getAutoTimeRequired()) {
+            return null;
+        }
+        ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser();
+        return new EnforcedAdmin(adminComponent, UserHandle.myUserId());
+    }
+
+    /**
+     * Checks if an admin has enforced minimum password quality requirements on the device.
+     *
+     * @return EnforcedAdmin Object containing the enforced admin component and admin user details,
+     * or {@code null} if no quality requirements are set. If the requirements are set by
+     * multiple device admins, then the admin component will be set to {@code null} and userId to
+     * {@link UserHandle#USER_NULL}.
+     *
+     */
+    public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context) {
+        final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        boolean isDisabledByMultipleAdmins = false;
+        ComponentName adminComponent = null;
+        List<ComponentName> admins = dpm.getActiveAdmins();
+        int quality;
+        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;
+                    }
+                }
+            }
+        }
+        EnforcedAdmin enforcedAdmin = null;
+        if (adminComponent != null) {
+            if (!isDisabledByMultipleAdmins) {
+                enforcedAdmin = new EnforcedAdmin(adminComponent, UserHandle.myUserId());
+            } else {
+                enforcedAdmin = new EnforcedAdmin();
+            }
+        }
+        return enforcedAdmin;
+    }
+
+    public static EnforcedAdmin getProfileOrDeviceOwnerOnCallingUser(Context context) {
+        final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser();
+        if (adminComponent != null) {
+            return new EnforcedAdmin(adminComponent, UserHandle.myUserId());
+        }
+        adminComponent = dpm.getProfileOwner();
+        if (adminComponent != null) {
+            return new EnforcedAdmin(adminComponent, UserHandle.myUserId());
+        }
+        return null;
+    }
+
     /**
      * Set the menu item as disabled by admin by adding a restricted padlock at the end of the
      * text and set the click listener which will send an intent to show the admin support details
-     * dialog.
+     * dialog. If the admin is null, remove the padlock and disabled color span. When the admin is
+     * null, we also set the OnMenuItemClickListener to null, so if you want to set a custom
+     * OnMenuItemClickListener, set it after calling this method.
      */
     public static void setMenuItemAsDisabledByAdmin(final Context context,
             final MenuItem item, final EnforcedAdmin admin) {
         SpannableStringBuilder sb = new SpannableStringBuilder(item.getTitle());
         removeExistingRestrictedSpans(sb);
 
-        final int disabledColor = context.getColor(R.color.disabled_text_color);
-        sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(),
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        ImageSpan image = new RestrictedLockImageSpan(context);
-        sb.append(" ", image, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        item.setTitle(sb);
+        if (admin != null) {
+            final int disabledColor = context.getColor(R.color.disabled_text_color);
+            sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(),
+                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+            ImageSpan image = new RestrictedLockImageSpan(context);
+            sb.append(" ", image, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
-        item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-            @Override
-            public boolean onMenuItemClick(MenuItem item) {
-                sendShowAdminSupportDetailsIntent(context, admin);
-                return true;
-            }
-        });
+            item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+                @Override
+                public boolean onMenuItemClick(MenuItem item) {
+                    sendShowAdminSupportDetailsIntent(context, admin);
+                    return true;
+                }
+            });
+        } else {
+            item.setOnMenuItemClickListener(null);
+        }
+        item.setTitle(sb);
     }
 
     private static void removeExistingRestrictedSpans(SpannableStringBuilder sb) {
@@ -178,7 +319,10 @@
         RestrictedLockImageSpan[] imageSpans = sb.getSpans(length - 1, length,
                 RestrictedLockImageSpan.class);
         for (ImageSpan span : imageSpans) {
+            final int start = sb.getSpanStart(span);
+            final int end = sb.getSpanEnd(span);
             sb.removeSpan(span);
+            sb.delete(start, end);
         }
         ForegroundColorSpan[] colorSpans = sb.getSpans(0, length, ForegroundColorSpan.class);
         for (ForegroundColorSpan span : colorSpans) {
@@ -190,18 +334,27 @@
      * Send the intent to trigger the {@link android.settings.ShowAdminSupportDetailsDialog}.
      */
     public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
-        Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
+        final Intent intent = getShowAdminSupportDetailsIntent(context, admin);
         int adminUserId = UserHandle.myUserId();
+        if (admin.userId != UserHandle.USER_NULL) {
+            adminUserId = admin.userId;
+        }
+        context.startActivityAsUser(intent, new UserHandle(adminUserId));
+    }
+
+    public static Intent getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
+        final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
         if (admin != null) {
             if (admin.component != null) {
                 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.component);
             }
+            int adminUserId = UserHandle.myUserId();
             if (admin.userId != UserHandle.USER_NULL) {
                 adminUserId = admin.userId;
             }
             intent.putExtra(Intent.EXTRA_USER_ID, adminUserId);
         }
-        context.startActivityAsUser(intent, new UserHandle(adminUserId));
+        return intent;
     }
 
     public static void setTextViewPadlock(Context context,
@@ -215,6 +368,25 @@
         textView.setText(sb);
     }
 
+    /**
+     * Takes a {@link android.widget.TextView} and applies an alpha so that the text looks like
+     * disabled and appends a padlock to the text. This assumes that there are no
+     * ForegroundColorSpans and RestrictedLockImageSpans used on the TextView.
+     */
+    public static void setTextViewAsDisabledByAdmin(Context context,
+            TextView textView, boolean disabled) {
+        final SpannableStringBuilder sb = new SpannableStringBuilder(textView.getText());
+        removeExistingRestrictedSpans(sb);
+        if (disabled) {
+            final int disabledColor = context.getColor(R.color.disabled_text_color);
+            sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(),
+                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+            final ImageSpan image = new RestrictedLockImageSpan(context);
+            sb.append(" ", image, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        }
+        textView.setText(sb);
+    }
+
     public static class EnforcedAdmin {
         public ComponentName component = null;
         public int userId = UserHandle.USER_NULL;
@@ -224,6 +396,42 @@
             this.userId = userId;
         }
 
+        public EnforcedAdmin(EnforcedAdmin other) {
+            if (other == null) {
+                throw new IllegalArgumentException();
+            }
+            this.component = other.component;
+            this.userId = other.userId;
+        }
+
         public EnforcedAdmin() {}
+
+        @Override
+        public boolean equals(Object object) {
+            if (object == this) return true;
+            if (!(object instanceof EnforcedAdmin)) return false;
+            EnforcedAdmin other = (EnforcedAdmin) object;
+            if (userId != other.userId) {
+                return false;
+            }
+            if ((component == null && other == null) ||
+                    (component != null && component.equals(other))) {
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "EnforcedAdmin{component=" + component + ",userId=" + userId + "}";
+        }
+
+        public void copyTo(EnforcedAdmin other) {
+            if (other == null) {
+                throw new IllegalArgumentException();
+            }
+            other.component = component;
+            other.userId = userId;
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
index 569017a..13a46d0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
@@ -79,6 +79,15 @@
         mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
     }
 
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (enabled && isDisabledByAdmin()) {
+            mHelper.setDisabledByAdmin(null);
+            return;
+        }
+        super.setEnabled(enabled);
+    }
+
     public void setDisabledByAdmin(EnforcedAdmin admin) {
         if (mHelper.setDisabledByAdmin(admin)) {
             notifyChanged();
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index f041504..06aba96 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -45,7 +45,7 @@
     private EnforcedAdmin mEnforcedAdmin;
     private String mAttrUserRestriction = null;
 
-    RestrictedPreferenceHelper(Context context, Preference preference,
+    public RestrictedPreferenceHelper(Context context, Preference preference,
             AttributeSet attrs) {
         mContext = context;
         mPreference = preference;
@@ -54,21 +54,21 @@
         mRestrictedPadlockPadding = mContext.getResources().getDimensionPixelSize(
                 R.dimen.restricted_lock_icon_padding);
 
-        mAttrUserRestriction = attrs.getAttributeValue(
-                R.styleable.RestrictedPreference_userRestriction);
-        final TypedArray attributes = context.obtainStyledAttributes(attrs,
-                R.styleable.RestrictedPreference);
-        final TypedValue userRestriction =
-                attributes.peekValue(R.styleable.RestrictedPreference_userRestriction);
-        CharSequence data = null;
-        if (userRestriction != null && userRestriction.type == TypedValue.TYPE_STRING) {
-            if (userRestriction.resourceId != 0) {
-                data = context.getText(userRestriction.resourceId);
-            } else {
-                data = userRestriction.string;
+        if (attrs != null) {
+            final TypedArray attributes = context.obtainStyledAttributes(attrs,
+                    R.styleable.RestrictedPreference);
+            final TypedValue userRestriction =
+                    attributes.peekValue(R.styleable.RestrictedPreference_userRestriction);
+            CharSequence data = null;
+            if (userRestriction != null && userRestriction.type == TypedValue.TYPE_STRING) {
+                if (userRestriction.resourceId != 0) {
+                    data = context.getText(userRestriction.resourceId);
+                } else {
+                    data = userRestriction.string;
+                }
             }
+            mAttrUserRestriction = data == null ? null : data.toString();
         }
-        mAttrUserRestriction = data == null ? null : data.toString();
     }
 
     /**
@@ -100,7 +100,7 @@
     /**
      * Disable / enable if we have been passed the restriction in the xml.
      */
-    protected void onAttachedToHierarchy() {
+    public void onAttachedToHierarchy() {
         if (mAttrUserRestriction != null) {
             checkRestrictionAndSetDisabled(mAttrUserRestriction, UserHandle.myUserId());
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 308477b0..84e2bff 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -79,6 +79,15 @@
         mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
     }
 
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (enabled && isDisabledByAdmin()) {
+            mHelper.setDisabledByAdmin(null);
+            return;
+        }
+        super.setEnabled(enabled);
+    }
+
     public void setDisabledByAdmin(EnforcedAdmin admin) {
         if (mHelper.setDisabledByAdmin(admin)) {
             notifyChanged();
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 72df96d..fa2226d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -2,7 +2,11 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
+import android.content.pm.Signature;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -138,4 +142,33 @@
 
         return statusString;
     }
+
+    /**
+     * Determine whether a package is a "system package", in which case certain things (like
+     * disabling notifications or disabling the package altogether) should be disallowed.
+     */
+    public static boolean isSystemPackage(PackageManager pm, PackageInfo pkg) {
+        if (sSystemSignature == null) {
+            sSystemSignature = new Signature[]{ getSystemSignature(pm) };
+        }
+        return sSystemSignature[0] != null && sSystemSignature[0].equals(getFirstSignature(pkg));
+    }
+
+    private static Signature[] sSystemSignature;
+
+    private static Signature getFirstSignature(PackageInfo pkg) {
+        if (pkg != null && pkg.signatures != null && pkg.signatures.length > 0) {
+            return pkg.signatures[0];
+        }
+        return null;
+    }
+
+    private static Signature getSystemSignature(PackageManager pm) {
+        try {
+            final PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
+            return getFirstSignature(sys);
+        } catch (NameNotFoundException e) {
+        }
+        return null;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
new file mode 100755
index 0000000..77f2e19
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import android.bluetooth.BluetoothA2dpSink;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothUuid;
+import android.content.Context;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import com.android.settingslib.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+final class A2dpSinkProfile implements LocalBluetoothProfile {
+    private static final String TAG = "A2dpSinkProfile";
+    private static boolean V = true;
+
+    private BluetoothA2dpSink mService;
+    private boolean mIsProfileReady;
+
+    private final LocalBluetoothAdapter mLocalAdapter;
+    private final CachedBluetoothDeviceManager mDeviceManager;
+
+    static final ParcelUuid[] SRC_UUIDS = {
+        BluetoothUuid.AudioSource,
+        BluetoothUuid.AdvAudioDist,
+    };
+
+    static final String NAME = "A2DPSink";
+    private final LocalBluetoothProfileManager mProfileManager;
+
+    // Order of this profile in device profiles list
+    private static final int ORDINAL = 5;
+
+    // These callbacks run on the main thread.
+    private final class A2dpSinkServiceListener
+            implements BluetoothProfile.ServiceListener {
+
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            if (V) Log.d(TAG,"Bluetooth service connected");
+            mService = (BluetoothA2dpSink) proxy;
+            // We just bound to the service, so refresh the UI for any connected A2DP devices.
+            List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+            while (!deviceList.isEmpty()) {
+                BluetoothDevice nextDevice = deviceList.remove(0);
+                CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
+                // we may add a new device here, but generally this should not happen
+                if (device == null) {
+                    Log.w(TAG, "A2dpSinkProfile found new device: " + nextDevice);
+                    device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
+                }
+                device.onProfileStateChanged(A2dpSinkProfile.this, BluetoothProfile.STATE_CONNECTED);
+                device.refresh();
+            }
+            mIsProfileReady=true;
+        }
+
+        public void onServiceDisconnected(int profile) {
+            if (V) Log.d(TAG,"Bluetooth service disconnected");
+            mIsProfileReady=false;
+        }
+    }
+
+    public boolean isProfileReady() {
+        return mIsProfileReady;
+    }
+
+    A2dpSinkProfile(Context context, LocalBluetoothAdapter adapter,
+            CachedBluetoothDeviceManager deviceManager,
+            LocalBluetoothProfileManager profileManager) {
+        mLocalAdapter = adapter;
+        mDeviceManager = deviceManager;
+        mProfileManager = profileManager;
+        mLocalAdapter.getProfileProxy(context, new A2dpSinkServiceListener(),
+                BluetoothProfile.A2DP_SINK);
+    }
+
+    public boolean isConnectable() {
+        return true;
+    }
+
+    public boolean isAutoConnectable() {
+        return true;
+    }
+
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (mService == null) return new ArrayList<BluetoothDevice>(0);
+        return mService.getDevicesMatchingConnectionStates(
+              new int[] {BluetoothProfile.STATE_CONNECTED,
+                         BluetoothProfile.STATE_CONNECTING,
+                         BluetoothProfile.STATE_DISCONNECTING});
+    }
+
+    public boolean connect(BluetoothDevice device) {
+        if (mService == null) return false;
+        List<BluetoothDevice> srcs = getConnectedDevices();
+        if (srcs != null) {
+            for (BluetoothDevice src : srcs) {
+                if (src.equals(device)) {
+                    // Connect to same device, Ignore it
+                    Log.d(TAG,"Ignoring Connect");
+                    return true;
+                }
+            }
+            for (BluetoothDevice src : srcs) {
+                mService.disconnect(src);
+            }
+        }
+        return mService.connect(device);
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        if (mService == null) return false;
+        // Downgrade priority as user is disconnecting the headset.
+        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
+            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        }
+        return mService.disconnect(device);
+    }
+
+    public int getConnectionStatus(BluetoothDevice device) {
+        if (mService == null) {
+            return BluetoothProfile.STATE_DISCONNECTED;
+        }
+        return mService.getConnectionState(device);
+    }
+
+    public boolean isPreferred(BluetoothDevice device) {
+        if (mService == null) return false;
+        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+    }
+
+    public int getPreferred(BluetoothDevice device) {
+        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+        return mService.getPriority(device);
+    }
+
+    public void setPreferred(BluetoothDevice device, boolean preferred) {
+        if (mService == null) return;
+        if (preferred) {
+            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
+                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            }
+        } else {
+            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+        }
+    }
+
+    boolean isA2dpPlaying() {
+        if (mService == null) return false;
+        List<BluetoothDevice> srcs = mService.getConnectedDevices();
+        if (!srcs.isEmpty()) {
+            if (mService.isA2dpPlaying(srcs.get(0))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public String toString() {
+        return NAME;
+    }
+
+    public int getOrdinal() {
+        return ORDINAL;
+    }
+
+    public int getNameResource(BluetoothDevice device) {
+        // we need to have same string in UI for even SINK Media Audio.
+        return R.string.bluetooth_profile_a2dp;
+    }
+
+    public int getSummaryResourceForDevice(BluetoothDevice device) {
+        int state = getConnectionStatus(device);
+        switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return R.string.bluetooth_a2dp_profile_summary_use_for;
+
+            case BluetoothProfile.STATE_CONNECTED:
+                return R.string.bluetooth_a2dp_profile_summary_connected;
+
+            default:
+                return Utils.getConnectionStateSummary(state);
+        }
+    }
+
+    public int getDrawableResource(BluetoothClass btClass) {
+        return R.drawable.ic_bt_headphones_a2dp;
+    }
+
+    protected void finalize() {
+        if (V) Log.d(TAG, "finalize()");
+        if (mService != null) {
+            try {
+                BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.A2DP_SINK,
+                                                                       mService);
+                mService = null;
+            }catch (Throwable t) {
+                Log.w(TAG, "Error cleaning up A2DP proxy", t);
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index d994841..7ee53a2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -851,7 +851,8 @@
 
                 case BluetoothProfile.STATE_DISCONNECTED:
                     if (profile.isProfileReady()) {
-                        if (profile instanceof A2dpProfile) {
+                        if ((profile instanceof A2dpProfile)||
+                            (profile instanceof A2dpSinkProfile)){
                             a2dpNotConnected = true;
                         } else if (profile instanceof HeadsetProfile) {
                             headsetNotConnected = true;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
old mode 100644
new mode 100755
index f935f31..9c5abf3
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
@@ -162,6 +162,10 @@
                 if (a2dp != null && a2dp.isA2dpPlaying()) {
                     return;
                 }
+                A2dpSinkProfile a2dpSink = mProfileManager.getA2dpSinkProfile();
+                if ((a2dpSink != null) && (a2dpSink.isA2dpPlaying())){
+                    return;
+                }
             }
 
             if (mAdapter.startDiscovery()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
old mode 100644
new mode 100755
index 8f5e1f1..b05e34c
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -17,6 +17,7 @@
 package com.android.settingslib.bluetooth;
 
 import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothA2dpSink;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothMap;
@@ -73,6 +74,7 @@
     private final BluetoothEventManager mEventManager;
 
     private A2dpProfile mA2dpProfile;
+    private A2dpSinkProfile mA2dpSinkProfile;
     private HeadsetProfile mHeadsetProfile;
     private MapProfile mMapProfile;
     private final HidProfile mHidProfile;
@@ -136,10 +138,10 @@
      * @param uuids
      */
     void updateLocalProfiles(ParcelUuid[] uuids) {
-        // A2DP
+        // A2DP SRC
         if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSource)) {
             if (mA2dpProfile == null) {
-                if(DEBUG) Log.d(TAG, "Adding local A2DP profile");
+                if(DEBUG) Log.d(TAG, "Adding local A2DP SRC profile");
                 mA2dpProfile = new A2dpProfile(mContext, mLocalAdapter, mDeviceManager, this);
                 addProfile(mA2dpProfile, A2dpProfile.NAME,
                         BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
@@ -148,6 +150,17 @@
             Log.w(TAG, "Warning: A2DP profile was previously added but the UUID is now missing.");
         }
 
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink)) {
+            if (mA2dpSinkProfile == null) {
+                if(DEBUG) Log.d(TAG, "Adding local A2DP Sink profile");
+                mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter, mDeviceManager, this);
+                addProfile(mA2dpSinkProfile, A2dpSinkProfile.NAME,
+                        BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);
+            }
+        } else if (mA2dpSinkProfile != null) {
+            Log.w(TAG, "Warning: A2DP Sink profile was previously added but the UUID is now missing.");
+        }
+
         // Headset / Handsfree
         if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) ||
             BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP_AG)) {
@@ -288,6 +301,10 @@
         if (profile != null) {
             return profile.isProfileReady();
         }
+        profile = mA2dpSinkProfile;
+        if (profile != null) {
+            return profile.isProfileReady();
+        }
         return false;
     }
 
@@ -295,6 +312,13 @@
         return mA2dpProfile;
     }
 
+    A2dpSinkProfile getA2dpSinkProfile() {
+        if ((mA2dpSinkProfile != null)&&(mA2dpSinkProfile.isProfileReady()))
+        return mA2dpSinkProfile;
+        else
+            return null;
+    }
+
     public HeadsetProfile getHeadsetProfile() {
         return mHeadsetProfile;
     }
@@ -345,6 +369,12 @@
             removedProfiles.remove(mA2dpProfile);
         }
 
+        if (BluetoothUuid.containsAnyUuid(uuids, A2dpSinkProfile.SRC_UUIDS) &&
+                mA2dpSinkProfile != null) {
+                profiles.add(mA2dpSinkProfile);
+                removedProfiles.remove(mA2dpSinkProfile);
+            }
+
         if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush) &&
             mOppProfile != null) {
             profiles.add(mOppProfile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
index 7b5bfb5..26e8303 100644
--- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.XmlResourceParser;
+import android.icu.text.TimeZoneNames;
 import android.text.BidiFormatter;
 import android.text.TextDirectionHeuristics;
 import android.text.TextUtils;
@@ -26,20 +27,18 @@
 
 import com.android.settingslib.R;
 
-import libcore.icu.TimeZoneNames;
-
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.TimeZone;
-import java.util.TreeSet;
 
 public class ZoneGetter {
     private static final String TAG = "ZoneGetter";
@@ -56,7 +55,8 @@
     public static String getTimeZoneOffsetAndName(TimeZone tz, Date now) {
         Locale locale = Locale.getDefault();
         String gmtString = getGmtOffsetString(locale, tz, now);
-        String zoneNameString = getZoneLongName(locale, tz, now);
+        TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
+        String zoneNameString = getZoneLongName(timeZoneNames, tz, now);
         if (zoneNameString == null) {
             return gmtString;
         }
@@ -68,6 +68,7 @@
     public static List<Map<String, Object>> getZonesList(Context context) {
         final Locale locale = Locale.getDefault();
         final Date now = new Date();
+        final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
 
         // The display name chosen for each zone entry depends on whether the zone is one associated
         // with the country of the user's chosen locale. For "local" zones we prefer the "long name"
@@ -85,25 +86,41 @@
         // selecting the wrong olson ids.
 
         // Get the list of olson ids to display to the user.
-        List<String> olsonIdsToDisplay = readTimezonesToDisplay(context);
+        List<String> olsonIdsToDisplayList = readTimezonesToDisplay(context);
+
+        // Store the information we are going to need more than once.
+        final int zoneCount = olsonIdsToDisplayList.size();
+        final String[] olsonIdsToDisplay = new String[zoneCount];
+        final TimeZone[] timeZones = new TimeZone[zoneCount];
+        final String[] gmtOffsetStrings = new String[zoneCount];
+        for (int i = 0; i < zoneCount; i++) {
+            String olsonId = olsonIdsToDisplayList.get(i);
+            olsonIdsToDisplay[i] = olsonId;
+            TimeZone tz = TimeZone.getTimeZone(olsonId);
+            timeZones[i] = tz;
+            gmtOffsetStrings[i] = getGmtOffsetString(locale, tz, now);
+        }
 
         // Create a lookup of local zone IDs.
-        Set<String> localZoneIds = new TreeSet<String>();
-        for (String olsonId : TimeZoneNames.forLocale(locale)) {
+        Set<String> localZoneIds = new HashSet<String>();
+        for (String olsonId : libcore.icu.TimeZoneNames.forLocale(locale)) {
             localZoneIds.add(olsonId);
         }
 
-        // Work out whether the long names for the local entries that we would show by default would
-        // be ambiguous.
-        Set<String> localZoneNames = new TreeSet<String>();
-        boolean localLongNamesAreAmbiguous = false;
-        for (String olsonId : olsonIdsToDisplay) {
+        // Work out whether the display names we would show by default would be ambiguous.
+        Set<String> localZoneNames = new HashSet<String>();
+        boolean useExemplarLocationForLocalNames = false;
+        for (int i = 0; i < zoneCount; i++) {
+            String olsonId = olsonIdsToDisplay[i];
             if (localZoneIds.contains(olsonId)) {
-                TimeZone tz = TimeZone.getTimeZone(olsonId);
-                String zoneLongName = getZoneLongName(locale, tz, now);
-                boolean longNameIsUnique = localZoneNames.add(zoneLongName);
-                if (!longNameIsUnique) {
-                    localLongNamesAreAmbiguous = true;
+                TimeZone tz = timeZones[i];
+                String displayName = getZoneLongName(timeZoneNames, tz, now);
+                if (displayName == null) {
+                    displayName = gmtOffsetStrings[i];
+                }
+                boolean nameIsUnique = localZoneNames.add(displayName);
+                if (!nameIsUnique) {
+                    useExemplarLocationForLocalNames = true;
                     break;
                 }
             }
@@ -111,15 +128,27 @@
 
         // Generate the list of zone entries to return.
         List<Map<String, Object>> zones = new ArrayList<Map<String, Object>>();
-        for (String olsonId : olsonIdsToDisplay) {
-            final TimeZone tz = TimeZone.getTimeZone(olsonId);
-            // Exemplar location display is the default. The only time we intend to display the long
-            // name is when the olsonId is local AND long names are not ambiguous.
-            boolean isLocalZoneId = localZoneIds.contains(olsonId);
-            boolean preferLongName = isLocalZoneId && !localLongNamesAreAmbiguous;
-            String displayName = getZoneDisplayName(locale, tz, now, preferLongName);
+        for (int i = 0; i < zoneCount; i++) {
+            String olsonId = olsonIdsToDisplay[i];
+            TimeZone tz = timeZones[i];
+            String gmtOffsetString = gmtOffsetStrings[i];
 
-            String gmtOffsetString = getGmtOffsetString(locale, tz, now);
+            boolean isLocalZoneId = localZoneIds.contains(olsonId);
+            boolean preferLongName = isLocalZoneId && !useExemplarLocationForLocalNames;
+            String displayName;
+            if (preferLongName) {
+                displayName = getZoneLongName(timeZoneNames, tz, now);
+            } else {
+                displayName = timeZoneNames.getExemplarLocationName(tz.getID());
+                if (displayName == null || displayName.isEmpty()) {
+                    // getZoneExemplarLocation can return null. Fall back to the long name.
+                    displayName = getZoneLongName(timeZoneNames, tz, now);
+                }
+            }
+            if (displayName == null  || displayName.isEmpty()) {
+                displayName = gmtOffsetString;
+            }
+
             int offsetMillis = tz.getOffset(now.getTime());
             Map<String, Object> displayEntry =
                     createDisplayEntry(tz, gmtOffsetString, displayName, offsetMillis);
@@ -138,30 +167,6 @@
         return map;
     }
 
-    /**
-     * Returns a name for the specific zone. If {@code preferLongName} is {@code true} then the
-     * long display name for the timezone will be used, otherwise the exemplar location will be
-     * preferred.
-     */
-    private static String getZoneDisplayName(Locale locale, TimeZone tz, Date now,
-            boolean preferLongName) {
-        String zoneNameString;
-        if (preferLongName) {
-            zoneNameString = getZoneLongName(locale, tz, now);
-        } else {
-            zoneNameString = getZoneExemplarLocation(locale, tz);
-            if (zoneNameString == null || zoneNameString.isEmpty()) {
-                // getZoneExemplarLocation can return null.
-                zoneNameString = getZoneLongName(locale, tz, now);
-            }
-        }
-        return zoneNameString;
-    }
-
-    private static String getZoneExemplarLocation(Locale locale, TimeZone tz) {
-        return TimeZoneNames.getExemplarLocation(locale.toString(), tz.getID());
-    }
-
     private static List<String> readTimezonesToDisplay(Context context) {
         List<String> olsonIds = new ArrayList<String>();
         try (XmlResourceParser xrp = context.getResources().getXml(R.xml.timezones)) {
@@ -193,10 +198,15 @@
         return olsonIds;
     }
 
-    private static String getZoneLongName(Locale locale, TimeZone tz, Date now) {
-        boolean daylight = tz.inDaylightTime(now);
-        // This returns a name if it can, or will fall back to GMT+0X:00 format.
-        return tz.getDisplayName(daylight, TimeZone.LONG, locale);
+    /**
+     * Returns the long name for the timezone for the given locale at the time specified.
+     * Can return {@code null}.
+     */
+    private static String getZoneLongName(TimeZoneNames names, TimeZone tz, Date now) {
+        TimeZoneNames.NameType nameType =
+                tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT
+                : TimeZoneNames.NameType.LONG_STANDARD;
+        return names.getDisplayName(tz.getID(), nameType, now.getTime());
     }
 
     private static String getGmtOffsetString(Locale locale, TimeZone tz, Date now) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/MobileDataController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
similarity index 93%
rename from packages/SettingsLib/src/com/android/settingslib/net/MobileDataController.java
rename to packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 642b60e..5d8668b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/MobileDataController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -42,11 +42,11 @@
 import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
 import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
 
-public class MobileDataController {
-    private static final String TAG = "MobileDataController";
+public class DataUsageController {
+    private static final String TAG = "DataUsageController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final long DEFAULT_WARNING_LEVEL = 2L * 1024 * 1024 * 1024;
+    public static final long DEFAULT_WARNING_LEVEL = 2L * 1024 * 1024 * 1024;
     private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES;
     private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
     private static final java.util.Formatter PERIOD_FORMATTER = new java.util.Formatter(
@@ -62,7 +62,7 @@
     private Callback mCallback;
     private NetworkNameProvider mNetworkController;
 
-    public MobileDataController(Context context) {
+    public DataUsageController(Context context) {
         mContext = context;
         mTelephonyManager = TelephonyManager.from(context);
         mConnectivityManager = ConnectivityManager.from(context);
@@ -109,16 +109,25 @@
         if (subscriberId == null) {
             return warn("no subscriber id");
         }
+        NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
+        template = NetworkTemplate.normalize(template, mTelephonyManager.getMergedSubscriberIds());
+
+        return getDataUsageInfo(template);
+    }
+
+    public DataUsageInfo getWifiDataUsageInfo() {
+        NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
+        return getDataUsageInfo(template);
+    }
+
+    public DataUsageInfo getDataUsageInfo(NetworkTemplate template) {
         final INetworkStatsSession session = getSession();
         if (session == null) {
             return warn("no stats session");
         }
-        NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
-        template = NetworkTemplate.normalize(template, mTelephonyManager.getMergedSubscriberIds());
-
         final NetworkPolicy policy = findNetworkPolicy(template);
         try {
-            final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELDS);
+            final NetworkStatsHistory history = session.getHistoryForNetwork(template, FIELDS);
             final long now = System.currentTimeMillis();
             final long start, end;
             if (policy != null && policy.cycleDay > 0) {
@@ -153,6 +162,7 @@
             }
             final long totalBytes = entry.rxBytes + entry.txBytes;
             final DataUsageInfo usage = new DataUsageInfo();
+            usage.startDate = start;
             usage.usageLevel = totalBytes;
             usage.period = formatDateRange(start, end);
             if (policy != null) {
@@ -238,6 +248,7 @@
     public static class DataUsageInfo {
         public String carrier;
         public String period;
+        public long startDate;
         public long limitLevel;
         public long warningLevel;
         public long usageLevel;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index cff8c23..2ee4b12 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -234,10 +234,13 @@
     }
 
     public boolean matches(WifiConfiguration config) {
-        if (config.isPasspoint() && mConfig != null && mConfig.isPasspoint())
+        if (config.isPasspoint() && mConfig != null && mConfig.isPasspoint()) {
             return config.FQDN.equals(mConfig.providerFriendlyName);
-        else
-            return ssid.equals(removeDoubleQuotes(config.SSID)) && security == getSecurity(config);
+        } else {
+            return ssid.equals(removeDoubleQuotes(config.SSID))
+                    && security == getSecurity(config)
+                    && (mConfig == null || mConfig.shared == config.shared);
+        }
     }
 
     public WifiConfiguration getConfig() {
@@ -394,33 +397,20 @@
             summary.append(String.format(format, mConfig.providerFriendlyName));
         } else if (mConfig != null && mConfig.hasNoInternetAccess()) {
             summary.append(mContext.getString(R.string.wifi_no_internet));
-        } else if (mConfig != null && ((mConfig.status == WifiConfiguration.Status.DISABLED &&
-                mConfig.disableReason != WifiConfiguration.DISABLED_UNKNOWN_REASON)
-               || mConfig.autoJoinStatus
-                >= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE)) {
-            if (mConfig.autoJoinStatus
-                    >= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE) {
-                if (mConfig.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE) {
-                    summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
-                } else if (mConfig.disableReason == WifiConfiguration.DISABLED_AUTH_FAILURE) {
+        } else if (mConfig != null && !mConfig.getNetworkSelectionStatus().isNetworkEnabled()) {
+            WifiConfiguration.NetworkSelectionStatus networkStatus =
+                    mConfig.getNetworkSelectionStatus();
+            switch (networkStatus.getNetworkSelectionDisableReason()) {
+                case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
                     summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
-                } else {
-                    summary.append(mContext.getString(R.string.wifi_disabled_wifi_failure));
-                }
-            } else {
-                switch (mConfig.disableReason) {
-                    case WifiConfiguration.DISABLED_AUTH_FAILURE:
-                        summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
-                        break;
-                    case WifiConfiguration.DISABLED_DHCP_FAILURE:
-                    case WifiConfiguration.DISABLED_DNS_FAILURE:
-                        summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
-                        break;
-                    case WifiConfiguration.DISABLED_UNKNOWN_REASON:
-                    case WifiConfiguration.DISABLED_ASSOCIATION_REJECT:
-                        summary.append(mContext.getString(R.string.wifi_disabled_generic));
-                        break;
-                }
+                    break;
+                case WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
+                case WifiConfiguration.NetworkSelectionStatus.DISABLED_DNS_FAILURE:
+                    summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
+                    break;
+                case WifiConfiguration.NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION:
+                    summary.append(mContext.getString(R.string.wifi_disabled_generic));
+                    break;
             }
         } else if (mRssi == Integer.MAX_VALUE) { // Wifi out of range
             summary.append(mContext.getString(R.string.wifi_not_in_range));
@@ -437,11 +427,11 @@
                 summary.append(" f=" + Integer.toString(mInfo.getFrequency()));
             }
             summary.append(" " + getVisibilityStatus());
-            if (mConfig != null && mConfig.autoJoinStatus > 0) {
-                summary.append(" (" + mConfig.autoJoinStatus);
-                if (mConfig.blackListTimestamp > 0) {
+            if (mConfig != null && !mConfig.getNetworkSelectionStatus().isNetworkEnabled()) {
+                summary.append(" (" + mConfig.getNetworkSelectionStatus().getNetworkStatusString());
+                if (mConfig.getNetworkSelectionStatus().getDisableTime() > 0) {
                     long now = System.currentTimeMillis();
-                    long diff = (now - mConfig.blackListTimestamp)/1000;
+                    long diff = (now - mConfig.getNetworkSelectionStatus().getDisableTime()) / 1000;
                     long sec = diff%60; //seconds
                     long min = (diff/60)%60; //minutes
                     long hour = (min/60)%60; //hours
@@ -452,17 +442,19 @@
                 }
                 summary.append(")");
             }
-            if (mConfig != null && mConfig.numIpConfigFailures > 0) {
-                summary.append(" ipf=").append(mConfig.numIpConfigFailures);
-            }
-            if (mConfig != null && mConfig.numConnectionFailures > 0) {
-                summary.append(" cf=").append(mConfig.numConnectionFailures);
-            }
-            if (mConfig != null && mConfig.numAuthFailures > 0) {
-                summary.append(" authf=").append(mConfig.numAuthFailures);
-            }
-            if (mConfig != null && mConfig.numNoInternetAccessReports > 0) {
-                summary.append(" noInt=").append(mConfig.numNoInternetAccessReports);
+
+            if (mConfig != null) {
+                WifiConfiguration.NetworkSelectionStatus networkStatus =
+                        mConfig.getNetworkSelectionStatus();
+                for (int index = WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
+                        index < WifiConfiguration.NetworkSelectionStatus
+                        .NETWORK_SELECTION_DISABLED_MAX; index++) {
+                    if (networkStatus.getDisableReasonCounter(index) != 0) {
+                        summary.append(" " + WifiConfiguration.NetworkSelectionStatus
+                                .getNetworkDisableReasonString(index) + "="
+                                + networkStatus.getDisableReasonCounter(index));
+                    }
+                }
             }
         }
         return summary.toString();
@@ -508,10 +500,6 @@
         Map<String, ScanResult> list = mScanResultCache.snapshot();
         // TODO: sort list by RSSI or age
         for (ScanResult result : list.values()) {
-            if (result.seen == 0)
-                continue;
-
-            if (result.autoJoinStatus != ScanResult.ENABLED) numBlackListed++;
 
             if (result.frequency >= LOWER_FREQ_5GHZ
                     && result.frequency <= HIGHER_FREQ_5GHZ) {
@@ -525,8 +513,6 @@
                 num24 = num24 + 1;
             }
 
-            // Ignore results seen, older than 20 seconds
-            if (now - result.seen > VISIBILITY_OUTDATED_AGE_IN_MILLI) continue;
 
             if (result.frequency >= LOWER_FREQ_5GHZ
                     && result.frequency <= HIGHER_FREQ_5GHZ) {
@@ -539,12 +525,6 @@
                     if (bssid != null && result.BSSID.equals(bssid)) scans5GHz.append("*");
                     scans5GHz.append("=").append(result.frequency);
                     scans5GHz.append(",").append(result.level);
-                    if (result.autoJoinStatus != 0) {
-                        scans5GHz.append(",st=").append(result.autoJoinStatus);
-                    }
-                    if (result.numIpConfigFailures != 0) {
-                        scans5GHz.append(",ipf=").append(result.numIpConfigFailures);
-                    }
                     scans5GHz.append("}");
                     n5++;
                 }
@@ -559,12 +539,6 @@
                     if (bssid != null && result.BSSID.equals(bssid)) scans24GHz.append("*");
                     scans24GHz.append("=").append(result.frequency);
                     scans24GHz.append(",").append(result.level);
-                    if (result.autoJoinStatus != 0) {
-                        scans24GHz.append(",st=").append(result.autoJoinStatus);
-                    }
-                    if (result.numIpConfigFailures != 0) {
-                        scans24GHz.append(",ipf=").append(result.numIpConfigFailures);
-                    }
                     scans24GHz.append("}");
                     n24++;
                 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WiFiConfigurationSerializer.java b/packages/SettingsProvider/src/com/android/providers/settings/WiFiConfigurationSerializer.java
index f9f1d3f..2317dbc 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/WiFiConfigurationSerializer.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WiFiConfigurationSerializer.java
@@ -48,6 +48,23 @@
      */
     private static int STATE_VERSION = 1;
 
+    /**
+     * write the Network selecton status to Byte Array
+     */
+    private static void writeNetworkSelectionStatus(WifiConfiguration config, DataOutputStream dest)
+            throws IOException {
+        WifiConfiguration.NetworkSelectionStatus status = config.getNetworkSelectionStatus();
+
+        dest.writeInt(status.getNetworkSelectionStatus());
+        dest.writeInt(status.getNetworkSelectionDisableReason());
+        for (int index = WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
+                index < WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX;
+                index++) {
+            dest.writeInt(status.getDisableReasonCounter(index));
+        }
+        dest.writeLong(status.getDisableTime());
+        writeString(dest, status.getNetworkSelectionBSSID());
+    }
 
     /**
      * Marshals a WifiConfig object into a byte-array.
@@ -64,12 +81,11 @@
                 out.writeInt(STATE_VERSION);
                 out.writeInt(wifiConfig.networkId);
                 out.writeInt(wifiConfig.status);
-                out.writeInt(wifiConfig.disableReason);
+                writeNetworkSelectionStatus(wifiConfig, out);
                 writeString(out, wifiConfig.SSID);
                 writeString(out, wifiConfig.BSSID);
                 out.writeInt(wifiConfig.apBand);
                 out.writeInt(wifiConfig.apChannel);
-                writeString(out, wifiConfig.autoJoinBSSID);
                 writeString(out, wifiConfig.FQDN);
                 writeString(out, wifiConfig.providerFriendlyName);
                 out.writeInt(wifiConfig.roamingConsortiumIds.length);
@@ -98,7 +114,6 @@
 
                 writeString(out, wifiConfig.dhcpServer);
                 writeString(out, wifiConfig.defaultGwMacAddress);
-                out.writeInt(wifiConfig.autoJoinStatus);
                 out.writeInt(wifiConfig.selfAdded ? 1 : 0);
                 out.writeInt(wifiConfig.didSelfAdd ? 1 : 0);
                 out.writeInt(wifiConfig.validatedInternetAccess ? 1 : 0);
@@ -108,14 +123,9 @@
                 out.writeInt(wifiConfig.lastUpdateUid);
                 writeString(out, wifiConfig.creatorName);
                 writeString(out, wifiConfig.lastUpdateName);
-                out.writeLong(wifiConfig.blackListTimestamp);
                 out.writeLong(wifiConfig.lastConnectionFailure);
                 out.writeLong(wifiConfig.lastRoamingFailure);
                 out.writeInt(wifiConfig.lastRoamingFailureReason);
-                out.writeLong(wifiConfig.roamingFailureBlackListTimeMilli);
-                out.writeLong(wifiConfig.numConnectionFailures);
-                out.writeLong(wifiConfig.numIpConfigFailures);
-                out.writeInt(wifiConfig.numAuthFailures);
                 out.writeInt(wifiConfig.numScorerOverride);
                 out.writeInt(wifiConfig.numScorerOverrideAndSwitchedNetwork);
                 out.writeInt(wifiConfig.numAssociation);
@@ -126,8 +136,6 @@
                 out.writeInt(wifiConfig.numTicksAtBadRSSI);
                 out.writeInt(wifiConfig.numTicksAtNotHighRSSI);
                 out.writeInt(wifiConfig.numUserTriggeredJoinAttempts);
-                out.writeInt(wifiConfig.autoJoinUseAggressiveJoinAttemptThreshold);
-                out.writeInt(wifiConfig.autoJoinBailedDueToLowRssi ? 1 : 0);
                 out.writeInt(wifiConfig.userApproved);
                 out.writeInt(wifiConfig.numNoInternetAccessReports);
                 out.writeInt(wifiConfig.noInternetAccessExpected ? 1 : 0);
@@ -140,6 +148,23 @@
     }
 
     /**
+     *
+     */
+    private static void readNetworkSelectionStatusFromByteArray(DataInputStream in,
+            WifiConfiguration config, int version) throws IOException {
+        WifiConfiguration.NetworkSelectionStatus status = config.getNetworkSelectionStatus();
+        status.setNetworkSelectionStatus(in.readInt());
+        status.setNetworkSelectionDisableReason(in.readInt());
+        for (int index = WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
+                index < WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX;
+                index++) {
+            status.setDisableReasonCounter(index, in.readInt());
+        }
+        status.setDisableTime(in.readLong());
+        status.setNetworkSelectionBSSID(readString(in, version));
+    }
+
+    /**
      * Unmarshals a byte array into a WifiConfig Object
      *
      * @param data - marshalled WifiConfig Object
@@ -157,12 +182,11 @@
 
             config.networkId = in.readInt();
             config.status = in.readInt();
-            config.disableReason = in.readInt();
+            readNetworkSelectionStatusFromByteArray(in, config, version);
             config.SSID = readString(in, version);
             config.BSSID = readString(in, version);
             config.apBand = in.readInt();
             config.apChannel = in.readInt();
-            config.autoJoinBSSID = readString(in, version);
             config.FQDN = readString(in, version);
             config.providerFriendlyName = readString(in, version);
             int numRoamingConsortiumIds = in.readInt();
@@ -195,7 +219,6 @@
 
             config.dhcpServer = readString(in, version);
             config.defaultGwMacAddress = readString(in, version);
-            config.autoJoinStatus = in.readInt();
             config.selfAdded = in.readInt() != 0;
             config.didSelfAdd = in.readInt() != 0;
             config.validatedInternetAccess = in.readInt() != 0;
@@ -205,14 +228,10 @@
             config.lastUpdateUid = in.readInt();
             config.creatorName = readString(in, version);
             config.lastUpdateName = readString(in, version);
-            config.blackListTimestamp = in.readLong();
             config.lastConnectionFailure = in.readLong();
             config.lastRoamingFailure = in.readLong();
             config.lastRoamingFailureReason = in.readInt();
             config.roamingFailureBlackListTimeMilli = in.readLong();
-            config.numConnectionFailures = in.readInt();
-            config.numIpConfigFailures = in.readInt();
-            config.numAuthFailures = in.readInt();
             config.numScorerOverride = in.readInt();
             config.numScorerOverrideAndSwitchedNetwork = in.readInt();
             config.numAssociation = in.readInt();
@@ -223,8 +242,6 @@
             config.numTicksAtBadRSSI = in.readInt();
             config.numTicksAtNotHighRSSI = in.readInt();
             config.numUserTriggeredJoinAttempts = in.readInt();
-            config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt();
-            config.autoJoinBailedDueToLowRssi = in.readInt() != 0;
             config.userApproved = in.readInt();
             config.numNoInternetAccessReports = in.readInt();
             config.noInternetAccessExpected = in.readInt() != 0;
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 b0450dd..b1dab44 100644
--- a/packages/Shell/res/values-de/strings.xml
+++ b/packages/Shell/res/values-de/strings.xml
@@ -19,9 +19,9 @@
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
     <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Fehlerbericht wird generiert"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Fehlerbericht erfasst"</string>
-    <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Wischen Sie nach links, um Ihren Fehlerbericht zu teilen."</string>
+    <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Wische nach links, um deinen Fehlerbericht zu teilen."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Tippen, um Fehlerbericht zu teilen"</string>
-    <string name="bugreport_confirm" msgid="5130698467795669780">"Fehlerberichte enthalten Daten aus verschiedenen Protokolldateien des Systems, darunter auch personenbezogene und private Daten. Teilen Sie Fehlerberichte nur mit Apps und Personen, denen Sie vertrauen."</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Fehlerberichte enthalten Daten aus verschiedenen Protokolldateien des Systems, darunter auch personenbezogene und private Daten. Teile Fehlerberichte nur mit Apps und Personen, denen du vertraust."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Diese Nachricht nächstes Mal zeigen"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Fehlerberichte"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Fehlerberichtdatei konnte nicht gelesen werden."</string>
@@ -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/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 5c807e1..874a946d 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -65,6 +65,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemProperties;
 import android.os.Vibrator;
@@ -108,7 +109,7 @@
  * </ol>
  */
 public class BugreportProgressService extends Service {
-    static final String TAG = "Shell";
+    private static final String TAG = "BugreportProgressService";
     private static final boolean DEBUG = false;
 
     private static final String AUTHORITY = "com.android.shell";
@@ -137,6 +138,7 @@
     static final String EXTRA_TITLE = "android.intent.extra.TITLE";
     static final String EXTRA_DESCRIPTION = "android.intent.extra.DESCRIPTION";
     static final String EXTRA_ORIGINAL_INTENT = "android.intent.extra.ORIGINAL_INTENT";
+    static final String EXTRA_INFO = "android.intent.extra.INFO";
 
     private static final int MSG_SERVICE_COMMAND = 1;
     private static final int MSG_POLL = 2;
@@ -325,7 +327,7 @@
                     takeScreenshot(pid, true);
                     break;
                 case INTENT_BUGREPORT_SHARE:
-                    shareBugreport(pid);
+                    shareBugreport(pid, (BugreportInfo) intent.getParcelableExtra(EXTRA_INFO));
                     break;
                 case INTENT_BUGREPORT_CANCEL:
                     cancel(pid);
@@ -483,6 +485,7 @@
         if (mProcesses.indexOfKey(pid) < 0) {
             Log.w(TAG, "PID not watched: " + pid);
         } else {
+            Log.d(TAG, "Removing PID " + pid);
             mProcesses.remove(pid);
         }
         stopSelfWhenDone();
@@ -675,6 +678,11 @@
         final int msgId;
         if (taken) {
             info.addScreenshot(screenshotFile);
+            if (info.finished) {
+                Log.d(TAG, "Screenshot finished after bugreport; updating share notification");
+                info.renameScreenshots(mScreenshotsDir);
+                sendBugreportNotification(mContext, info);
+            }
             msgId = R.string.bugreport_screenshot_taken;
         } else {
             // TODO: try again using Framework APIs instead of relying on screencap.
@@ -814,12 +822,13 @@
      * Shares the bugreport upon user's request by issuing a {@link Intent#ACTION_SEND_MULTIPLE}
      * intent, but issuing a warning dialog the first time.
      */
-    private void shareBugreport(int pid) {
-        final BugreportInfo info = getInfo(pid);
+    private void shareBugreport(int pid, BugreportInfo sharedInfo) {
+        BugreportInfo info = getInfo(pid);
         if (info == null) {
-            // Should not happen, so log if it does...
-            Log.e(TAG, "INTERNAL ERROR: no info for PID " + pid + ": " + mProcesses);
-            return;
+            // Service was terminated but notification persisted
+            info = sharedInfo;
+            Log.d(TAG, "shareBugreport(): no info for PID " + pid + " on managed processes ("
+                    + mProcesses + "), using info from intent instead (" + info + ")");
         }
 
         addDetailsToZipFile(info);
@@ -850,6 +859,7 @@
         shareIntent.setClass(context, BugreportProgressService.class);
         shareIntent.setAction(INTENT_BUGREPORT_SHARE);
         shareIntent.putExtra(EXTRA_PID, info.pid);
+        shareIntent.putExtra(EXTRA_INFO, info);
 
         final String title = context.getString(R.string.bugreport_finished_title);
         final Notification.Builder builder = new Notification.Builder(context)
@@ -919,6 +929,15 @@
      * description will be saved on {@code description.txt}.
      */
     private void addDetailsToZipFile(BugreportInfo info) {
+        if (info.bugreportFile == null) {
+            // One possible reason is a bug in the Parcelization code.
+            Log.e(TAG, "INTERNAL ERROR: no bugreportFile on " + info);
+            return;
+        }
+        if (TextUtils.isEmpty(info.title) && TextUtils.isEmpty(info.description)) {
+            Log.d(TAG, "Not touching zip file since neither title nor description are set");
+            return;
+        }
         // It's not possible to add a new entry into an existing file, so we need to create a new
         // zip, copy all entries, then rename it.
         final File dir = info.bugreportFile.getParentFile();
@@ -1281,7 +1300,7 @@
     /**
      * Information about a bugreport process while its in progress.
      */
-    private static final class BugreportInfo {
+    private static final class BugreportInfo implements Parcelable {
         private final Context context;
 
         /**
@@ -1325,6 +1344,11 @@
         long lastUpdate = System.currentTimeMillis();
 
         /**
+         * Time of the last progress update when Parcel was created.
+         */
+        String formattedLastUpdate;
+
+        /**
          * Path of the main bugreport file.
          */
         File bugreportFile;
@@ -1403,6 +1427,11 @@
         }
 
         String getFormattedLastUpdate() {
+            if (context == null) {
+                // Restored from Parcel
+                return formattedLastUpdate == null ?
+                        Long.toString(lastUpdate) : formattedLastUpdate;
+            }
             return DateUtils.formatDateTime(context, lastUpdate,
                     DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
         }
@@ -1416,5 +1445,74 @@
                     + "\n\tprogress: " + progress + "/" + max + "(" + percent + ")"
                     + "\n\tlast_update: " + getFormattedLastUpdate();
         }
+
+        // Parcelable contract
+        protected BugreportInfo(Parcel in) {
+            context = null;
+            pid = in.readInt();
+            name = in.readString();
+            title = in.readString();
+            description = in.readString();
+            max = in.readInt();
+            progress = in.readInt();
+            lastUpdate = in.readLong();
+            formattedLastUpdate = in.readString();
+            bugreportFile = readFile(in);
+
+            int screenshotSize = in.readInt();
+            for (int i = 1; i <= screenshotSize; i++) {
+                  screenshotFiles.add(readFile(in));
+            }
+
+            finished = in.readInt() == 1;
+            screenshotCounter = in.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(pid);
+            dest.writeString(name);
+            dest.writeString(title);
+            dest.writeString(description);
+            dest.writeInt(max);
+            dest.writeInt(progress);
+            dest.writeLong(lastUpdate);
+            dest.writeString(getFormattedLastUpdate());
+            writeFile(dest, bugreportFile);
+
+            dest.writeInt(screenshotFiles.size());
+            for (File screenshotFile : screenshotFiles) {
+                writeFile(dest, screenshotFile);
+            }
+
+            dest.writeInt(finished ? 1 : 0);
+            dest.writeInt(screenshotCounter);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        private void writeFile(Parcel dest, File file) {
+            dest.writeString(file == null ? null : file.getPath());
+        }
+
+        private File readFile(Parcel in) {
+            final String path = in.readString();
+            return path == null ? null : new File(path);
+        }
+
+        public static final Parcelable.Creator<BugreportInfo> CREATOR =
+                new Parcelable.Creator<BugreportInfo>() {
+            public BugreportInfo createFromParcel(Parcel source) {
+                return new BugreportInfo(source);
+            }
+
+            public BugreportInfo[] newArray(int size) {
+                return new BugreportInfo[size];
+            }
+        };
+
     }
 }
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index c8898b9..9afa900 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -19,7 +19,6 @@
 import static com.android.shell.BugreportProgressService.EXTRA_BUGREPORT;
 import static com.android.shell.BugreportProgressService.EXTRA_ORIGINAL_INTENT;
 import static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_FINISHED;
-import static com.android.shell.BugreportProgressService.TAG;
 import static com.android.shell.BugreportProgressService.getFileExtra;
 
 import java.io.File;
@@ -37,6 +36,7 @@
  * {@link Intent#ACTION_SEND_MULTIPLE}.
  */
 public class BugreportReceiver extends BroadcastReceiver {
+    private static final String TAG = "BugreportReceiver";
 
     /**
      * Always keep the newest 8 bugreport files; 4 reports and 4 screenshots are
@@ -74,7 +74,11 @@
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
-                FileUtils.deleteOlderFiles(bugreportFile.getParentFile(), minCount, minAge);
+                try {
+                    FileUtils.deleteOlderFiles(bugreportFile.getParentFile(), minCount, minAge);
+                } catch (RuntimeException e) {
+                    Log.e(TAG, "RuntimeException deleting old files", e);
+                }
                 result.finish();
                 return null;
             }
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index d1a07ea..52e1b56 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -65,6 +65,7 @@
 import android.util.Log;
 
 import com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener;
+import com.android.shell.BugreportProgressService;
 
 /**
  * Integration tests for {@link BugreportReceiver}.
@@ -89,6 +90,9 @@
     // Timeout for UI operations, in milliseconds.
     private static final int TIMEOUT = (int) BugreportProgressService.POLLING_FREQUENCY * 4;
 
+    // Timeout for when waiting for a screenshot to finish.
+    private static final int SAFE_SCREENSHOT_DELAY = SCREENSHOT_DELAY_SECONDS + 10;
+
     private static final String BUGREPORTS_DIR = "bugreports";
     private static final String BUGREPORT_FILE = "test_bugreport.txt";
     private static final String ZIP_FILE = "test_bugreport.zip";
@@ -109,6 +113,7 @@
     private static final String NO_NAME = null;
     private static final String NO_SCREENSHOT = null;
     private static final String NO_TITLE = null;
+    private static final Integer NO_PID = null;
 
     private String mDescription;
 
@@ -122,6 +127,7 @@
 
     @Override
     protected void setUp() throws Exception {
+        Log.i(TAG, "#### setup() on " + getName());
         Instrumentation instrumentation = getInstrumentation();
         mContext = instrumentation.getTargetContext();
         mUiBot = new UiBot(UiDevice.getInstance(instrumentation), TIMEOUT);
@@ -164,13 +170,21 @@
 
         Bundle extras =
                 sendBugreportFinishedAndGetSharedIntent(PID, mPlainTextPath, mScreenshotPath);
-        assertActionSendMultiple(extras, BUGREPORT_FILE, BUGREPORT_CONTENT, PID, ZIP_FILE,
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, PID, ZIP_FILE,
                 NAME, NO_TITLE, NO_DESCRIPTION, 1, true);
 
         assertServiceNotRunning();
     }
 
     public void testProgress_takeExtraScreenshot() throws Exception {
+        takeExtraScreenshotTest(false);
+    }
+
+    public void testProgress_takeExtraScreenshotServiceDiesAfterScreenshotTaken() throws Exception {
+        takeExtraScreenshotTest(true);
+    }
+
+    private void takeExtraScreenshotTest(boolean serviceDies) throws Exception {
         resetProperties();
         sendBugreportStarted(1000);
 
@@ -179,14 +193,49 @@
         assertScreenshotButtonEnabled(false);
         waitForScreenshotButtonEnabled(true);
 
-        Bundle extras =
-                sendBugreportFinishedAndGetSharedIntent(PID, mPlainTextPath, mScreenshotPath);
-        assertActionSendMultiple(extras, BUGREPORT_FILE, BUGREPORT_CONTENT, PID, ZIP_FILE,
+        sendBugreportFinished(PID, mPlainTextPath, mScreenshotPath);
+
+        if (serviceDies) {
+            waitShareNotification();
+            killService();
+        }
+
+        Bundle extras = acceptBugreportAndGetSharedIntent();
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, PID, ZIP_FILE,
                 NAME, NO_TITLE, NO_DESCRIPTION, 2, true);
 
         assertServiceNotRunning();
     }
 
+    public void testScreenshotFinishesAfterBugreport() throws Exception {
+        screenshotFinishesAfterBugreportTest(false);
+    }
+
+    public void testScreenshotFinishesAfterBugreportAndServiceDiesBeforeSharing() throws Exception {
+        screenshotFinishesAfterBugreportTest(true);
+    }
+
+    private void screenshotFinishesAfterBugreportTest(boolean serviceDies) throws Exception {
+        resetProperties();
+
+        sendBugreportStarted(1000);
+        sendBugreportFinished(PID, mPlainTextPath, NO_SCREENSHOT);
+        waitShareNotification();
+
+        // There's no indication in the UI about the screenshot finish, so just sleep like a baby...
+        Thread.sleep(SAFE_SCREENSHOT_DELAY * DateUtils.SECOND_IN_MILLIS);
+
+        if (serviceDies) {
+            killService();
+        }
+
+        Bundle extras = acceptBugreportAndGetSharedIntent();
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT, PID, ZIP_FILE,
+                NAME, NO_TITLE, NO_DESCRIPTION, 1, true);
+
+        assertServiceNotRunning();
+    }
+
     public void testProgress_changeDetailsInvalidInput() throws Exception {
 
         resetProperties();
@@ -227,7 +276,7 @@
 
         Bundle extras = sendBugreportFinishedAndGetSharedIntent(PID, mPlainTextPath,
                 mScreenshotPath);
-        assertActionSendMultiple(extras, BUGREPORT_FILE, BUGREPORT_CONTENT, PID, TITLE,
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, PID, TITLE,
                 NEW_NAME, TITLE, mDescription, 1, true);
 
         assertServiceNotRunning();
@@ -266,7 +315,7 @@
 
         Bundle extras = sendBugreportFinishedAndGetSharedIntent(PID,
                 plainText? mPlainTextPath : mZipPath, mScreenshotPath);
-        assertActionSendMultiple(extras, BUGREPORT_FILE, BUGREPORT_CONTENT, PID, TITLE,
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, PID, TITLE,
                 NEW_NAME, TITLE, mDescription, 1, true);
 
         assertServiceNotRunning();
@@ -317,8 +366,8 @@
 
         // Finally, share bugreport.
         Bundle extras = acceptBugreportAndGetSharedIntent();
-        assertActionSendMultiple(extras, BUGREPORT_FILE, BUGREPORT_CONTENT, PID, TITLE,
-                NAME, TITLE, mDescription, 1, waitScreenshot);
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, PID, TITLE,
+                NAME, TITLE, mDescription, 1, true);
 
         assertServiceNotRunning();
     }
@@ -328,7 +377,7 @@
         BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_SHOW);
 
         // Send notification and click on share.
-        sendBugreportFinished(null, mPlainTextPath, null);
+        sendBugreportFinished(NO_PID, mPlainTextPath, null);
         acceptBugreport();
 
         // Handle the warning
@@ -350,6 +399,13 @@
         assertEquals("Didn't change state", BugreportPrefs.STATE_HIDE, newState);
     }
 
+    public void testShareBugreportAfterServiceDies() throws Exception {
+        sendBugreportFinished(NO_PID, mPlainTextPath, NO_SCREENSHOT);
+        killService();
+        Bundle extras = acceptBugreportAndGetSharedIntent();
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
+    }
+
     public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception {
         Bundle extras = sendBugreportFinishedAndGetSharedIntent(mPlainTextPath, mScreenshotPath);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
@@ -444,6 +500,13 @@
     }
 
     /**
+     * Waits for the notification to share the finished bugreport.
+     */
+    private void waitShareNotification() {
+        mUiBot.getNotification(mContext.getString(R.string.bugreport_finished_title));
+    }
+
+    /**
      * Accepts the notification to share the finished bugreport.
      */
     private void acceptBugreport() {
@@ -512,7 +575,8 @@
             expectedNumberScreenshots ++; // Add screenshot received by dumpstate
         }
         int expectedSize = expectedNumberScreenshots + 1; // All screenshots plus the bugreport file
-        assertEquals("wrong number of attachments", expectedSize, attachments.size());
+        assertEquals("wrong number of attachments (" + attachments + ")",
+                expectedSize, attachments.size());
 
         // Need to interact through all attachments, since order is not guaranteed.
         Uri zipUri = null;
@@ -607,6 +671,15 @@
         assertFalse("Service '" + service + "' is still running", isServiceRunning(service));
     }
 
+    private void killService() {
+        waitForService(true);
+        Log.v(TAG, "Stopping service");
+        boolean stopped = mContext.stopService(new Intent(mContext, BugreportProgressService.class));
+        Log.d(TAG, "stopService returned " + stopped);
+        waitForService(false);
+        assertServiceNotRunning();  // Sanity check.
+    }
+
     private boolean isServiceRunning(String name) {
         ActivityManager manager = (ActivityManager) mContext
                 .getSystemService(Context.ACTIVITY_SERVICE);
@@ -618,6 +691,33 @@
         return false;
     }
 
+    private void waitForService(boolean expectRunning) {
+        String service = BugreportProgressService.class.getName();
+        boolean actualRunning;
+        for (int i = 1; i <= 5; i++) {
+            actualRunning = isServiceRunning(service);
+            Log.d(TAG, "Attempt " + i + " to check status of service '"
+                    + service + "': expected=" + expectRunning + ", actual= " + actualRunning);
+            if (actualRunning == expectRunning) {
+                return;
+            }
+            try {
+                Thread.sleep(DateUtils.SECOND_IN_MILLIS);
+            } catch (InterruptedException e) {
+                Log.w(TAG, "thread interrupted");
+                Thread.currentThread().interrupt();
+            }
+        }
+        if (!expectRunning) {
+            // Typically happens when service is waiting for a screenshot to finish.
+            Log.w(TAG, "Service didn't stop; try to kill it again");
+            killService();
+            return;
+        }
+
+        fail("Service status didn't change to " + expectRunning);
+    }
+
     private static void createTextFile(String path, String content) throws IOException {
         Log.v(TAG, "createFile(" + path + ")");
         try (Writer writer = new BufferedWriter(new OutputStreamWriter(
@@ -669,7 +769,7 @@
 
     private UiObject waitForScreenshotButtonEnabled(boolean expectedEnabled) throws Exception {
         UiObject screenshotButton = getScreenshotButton();
-        int maxAttempts = SCREENSHOT_DELAY_SECONDS + 5;
+        int maxAttempts = SAFE_SCREENSHOT_DELAY;
         int i = 0;
         do {
             boolean enabled = screenshotButton.isEnabled();
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6201fd6..c1f97a8 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -146,6 +146,15 @@
     <!-- Access battery information -->
     <uses-permission android:name="android.permission.BATTERY_STATS" />
 
+    <!-- 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"
@@ -306,6 +315,27 @@
             android:launchMode="singleTop"
             android:excludeFromRecents="true" />
 
+        <!-- started from PipUI -->
+        <activity
+            android:name="com.android.systemui.tv.pip.PipMenuActivity"
+            android:exported="true"
+            android:theme="@style/PipTheme"
+            android:launchMode="singleTop"
+            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|layoutDirection"
+            android:resizeable="true"
+            android:supportsPictureInPicture="true"
+            androidprv:alwaysFocusable="true"
+            android:excludeFromRecents="true" />
+        <activity
+            android:name="com.android.systemui.tv.pip.PipOverlayActivity"
+            android:exported="true"
+            android:theme="@style/PipTheme"
+            android:launchMode="singleTop"
+            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|layoutDirection"
+            android:resizeable="true"
+            android:supportsPictureInPicture="true"
+            android:excludeFromRecents="true" />
+
         <!-- platform logo easter egg activity -->
         <activity
             android:name=".DessertCase"
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index bc18221..2ea8c9c 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -13,6 +13,7 @@
 -keep class com.android.systemui.statusbar.car.CarStatusBar
 -keep class com.android.systemui.statusbar.phone.PhoneStatusBar
 -keep class com.android.systemui.statusbar.tv.TvStatusBar
+-keep class com.android.systemui.SystemUIFactory
 
 -keepclassmembers class ** {
     public void onBusEvent(**);
diff --git a/packages/SystemUI/res/color/qs_tile_text.xml b/packages/SystemUI/res/color/qs_tile_text.xml
new file mode 100644
index 0000000..90e0bce
--- /dev/null
+++ b/packages/SystemUI/res/color/qs_tile_text.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:color="@color/qs_tile_disabled_color" />
+    <item android:color="#B3FFFFFF" /> <!-- 70% white -->
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_user_detail_name.xml b/packages/SystemUI/res/color/qs_user_detail_name.xml
index 57f7e65..35c7a4f 100644
--- a/packages/SystemUI/res/color/qs_user_detail_name.xml
+++ b/packages/SystemUI/res/color/qs_user_detail_name.xml
@@ -18,5 +18,6 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_activated="true" android:color="@color/current_user_border_color" />
+    <item android:state_enabled="false" android:color="@color/qs_tile_disabled_color" />
     <item android:color="#66ffffff" /> <!-- 40% white -->
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_arrow.xml b/packages/SystemUI/res/drawable/car_ic_arrow.xml
new file mode 100644
index 0000000..9d292cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_ic_arrow.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M14.0,20.0l10.0,10.0 10.0,-10.0z"/>
+    <path
+        android:pathData="M0 0h48v48H0z"
+        android:fillColor="#00000000"/>
+</vector>
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/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
new file mode 100644
index 0000000..479f18d
--- /dev/null
+++ b/packages/SystemUI/res/layout/car_navigation_button.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.systemui.statusbar.car.CarNavigationButton
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_height="match_parent"
+        android:layout_width="wrap_content"
+        android:orientation="horizontal"
+        android:background="?android:attr/selectableItemBackground">
+    <com.android.keyguard.AlphaOptimizedImageButton
+            android:id="@+id/car_nav_button_icon"
+            android:layout_height="match_parent"
+            android:layout_width="wrap_content"
+            android:layout_centerInParent="true"
+            android:animateLayoutChanges="true">
+    </com.android.keyguard.AlphaOptimizedImageButton>
+
+    <com.android.keyguard.AlphaOptimizedImageButton
+            android:id="@+id/car_nav_button_more_icon"
+            android:layout_height="match_parent"
+            android:layout_width="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_toRightOf="@+id/car_nav_button_icon"
+            android:animateLayoutChanges="true">
+    </com.android.keyguard.AlphaOptimizedImageButton>
+</com.android.systemui.statusbar.car.CarNavigationButton>
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/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml
index 071b7c8..03451b4 100644
--- a/packages/SystemUI/res/layout/notification_guts.xml
+++ b/packages/SystemUI/res/layout/notification_guts.xml
@@ -25,15 +25,15 @@
         android:gravity="top|start"
         android:orientation="vertical"
         android:paddingStart="@*android:dimen/notification_content_margin_start"
-        android:paddingEnd="@*android:dimen/notification_content_margin_end"
-        android:background="@color/notification_guts_text_color" >
+        android:paddingEnd="8dp"
+        android:background="@color/notification_guts_bg_color" >
 
     <!-- header -->
     <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingBottom="8dp"
-            android:paddingTop="8dp"
+            android:layout_height="30dp"
+            android:paddingTop="9dp"
+            android:paddingEnd="8dp"
             android:id="@+id/notification_guts_header"
             android:orientation="horizontal"
             android:layout_gravity="center_vertical|start">
@@ -42,25 +42,21 @@
                 android:id="@android:id/icon"
                 android:layout_width="18dp"
                 android:layout_height="18dp"
-                android:layout_marginEnd="3dp"
+                android:layout_marginEnd="6dp"
                 android:src="@android:drawable/arrow_down_float" />
         <TextView
-                            android:id="@+id/pkgname"
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:textAppearance="@android:style/TextAppearance.Material.Notification.Info"
-                            android:layout_marginStart="3dp"
-                            android:layout_marginEnd="4dp"
-                            android:textColor="@color/notification_guts_title_color" />
+                android:id="@+id/pkgname"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                style="@style/TextAppearance.NotificationGuts.Header" />
         <TextView
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:id="@+id/debug_info"
-                            android:layout_weight="0"
-                            android:textAppearance="@android:style/TextAppearance.Material.Notification.Time"
-                            android:layout_gravity="bottom|start"
-                            android:visibility="gone"
-                            android:textColor="#ffffff" />
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/debug_info"
+                android:layout_weight="0"
+                style="@style/TextAppearance.NotificationGuts.Header"
+                android:layout_gravity="bottom|start"
+                android:visibility="gone" />
     </LinearLayout>
     <!-- Importance slider -->
     <LinearLayout
@@ -70,16 +66,17 @@
             android:orientation="vertical"
             android:clickable="false"
             android:focusable="false"
-            android:paddingBottom="8dip">
+            android:paddingBottom="8dip"
+            android:paddingEnd="8dp" >
         <TextView
                 android:id="@+id/title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
-                android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-                android:textColor="@color/notification_guts_text_color"
+                style="@style/TextAppearance.NotificationGuts.Primary"
                 android:ellipsize="marquee"
-                android:fadingEdge="horizontal"/>
+                android:fadingEdge="horizontal"
+                android:paddingBottom="2dp"/>
 
         <TextView
                 android:id="@+id/summary"
@@ -87,38 +84,41 @@
                 android:layout_height="wrap_content"
                 android:layout_alignStart="@android:id/title"
                 android:textAlignment="viewStart"
-                android:textAppearance="@android:style/TextAppearance.Material.Body1"
-                android:textColor="@color/notification_guts_title_color"
+                style="@style/TextAppearance.NotificationGuts.Secondary"
                 android:maxLines="3"
-                android:minLines="2" />
+                android:minLines="2"
+                android:paddingBottom="4dp" />
 
         <FrameLayout
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
+                android:layout_height="48dp"
                 android:paddingTop="8dp" >
 
             <ImageView
                     android:id="@+id/low_importance"
-                    android:src="@android:drawable/ic_menu_close_clear_cancel"
+                    android:src="@*android:drawable/ic_notification_block"
                     android:layout_gravity="center_vertical|start"
                     android:layout_width="24dp"
                     android:layout_height="24dp" />
 
             <SeekBar
                     android:id="@+id/seekbar"
-                    android:layout_marginStart="24dp"
-                    android:layout_marginEnd="24dp"
+                    android:layout_marginStart="56dp"
+                    android:layout_marginEnd="56dp"
                     android:layout_gravity="center_vertical"
                     android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
+                    android:layout_height="48dp"
                     android:focusable="true"
                     android:background="#00ffffff"
-                    android:thumbTint="@android:color/white"
-                    android:progressTint="@android:color/white" />
+                    android:progressBackgroundTint="@color/notification_guts_secondary_slider_color"
+                    android:thumbTint="@color/notification_guts_slider_color"
+                    android:progressTint="@color/notification_guts_slider_color"
+                    style="@android:style/Widget.Material.SeekBar.Discrete"
+                    android:tickMarkTint="@android:color/black" />
 
             <ImageView
                     android:id="@+id/max_importance"
-                    android:src="@android:drawable/ic_popup_reminder"
+                    android:src="@*android:drawable/ic_notification_alert"
                     android:layout_gravity="center_vertical|end"
                     android:layout_width="24dp"
                     android:layout_height="24dp"/>
@@ -128,19 +128,22 @@
         <RadioGroup
                     android:id="@+id/apply_to"
                     android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:paddingTop="8dp">
+                    android:layout_height="wrap_content" >
             <RadioButton android:id="@+id/apply_to_topic"
                          android:layout_width="wrap_content"
-                         android:layout_height="wrap_content"
-                         android:textColor="@color/notification_guts_text_color"
-                         android:visibility="gone"/>
+                         android:layout_height="48dp"
+                         style="@style/TextAppearance.NotificationGuts.Primary"
+                         android:visibility="gone"
+                         android:buttonTint="#858383"
+            />
             <RadioButton android:id="@+id/apply_to_app"
                          android:layout_width="wrap_content"
-                         android:layout_height="wrap_content"
+                         android:layout_height="48dp"
                          android:text="@string/apply_to_app"
-                         android:textColor="@color/notification_guts_text_color"
-                         android:visibility="gone"/>
+                         style="@style/TextAppearance.NotificationGuts.Primary"
+                         android:visibility="gone"
+                         android:buttonTint="#858383"
+            />
         </RadioGroup>
     </LinearLayout>
     <!-- buttons -->
@@ -148,29 +151,30 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:gravity="end"
-            android:paddingTop="8dp"
-            android:paddingBottom="16dp" >
+            android:paddingBottom="8dp" >
 
         <TextView
             android:id="@+id/more_settings"
             android:text="@string/notification_more_settings"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="@style/TextAppearance.NotificationGuts"
+            android:layout_height="48dp"
+            style="@style/TextAppearance.NotificationGuts.Button"
             android:background="@drawable/btn_borderless_rect"
             android:gravity="center"
-            android:paddingEnd="24dp"
-            android:paddingStart="12dp"
+            android:paddingEnd="8dp"
+            android:paddingStart="8dp"
             android:focusable="true" />
 
         <TextView
             android:id="@+id/done"
             android:text="@string/notification_done"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="@style/TextAppearance.NotificationGuts"
+            android:layout_height="48dp"
+            style="@style/TextAppearance.NotificationGuts.Button"
             android:background="@drawable/btn_borderless_rect"
             android:gravity="center"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
             android:focusable="true"/>
     </LinearLayout>
 </com.android.systemui.statusbar.NotificationGuts>
diff --git a/packages/SystemUI/res/layout/notification_icon_area.xml b/packages/SystemUI/res/layout/notification_icon_area.xml
new file mode 100644
index 0000000..c5b4e84
--- /dev/null
+++ b/packages/SystemUI/res/layout/notification_icon_area.xml
@@ -0,0 +1,35 @@
+<?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
+  -->
+<com.android.keyguard.AlphaOptimizedLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/notification_icon_area_inner"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    <com.android.systemui.statusbar.StatusBarIconView
+        android:id="@+id/moreIcon"
+        android:layout_width="@dimen/status_bar_icon_size"
+        android:layout_height="match_parent"
+        android:src="@drawable/stat_notify_more"
+        android:visibility="gone" />
+    <com.android.systemui.statusbar.phone.IconMerger
+        android:id="@+id/notificationIcons"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_alignParentStart="true"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"/>
+</com.android.keyguard.AlphaOptimizedLinearLayout>
\ No newline at end of file
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_detail_item.xml b/packages/SystemUI/res/layout/qs_detail_item.xml
index 6facb71..ccdddf7 100644
--- a/packages/SystemUI/res/layout/qs_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_detail_item.xml
@@ -60,6 +60,7 @@
         android:clickable="true"
         android:focusable="true"
         android:scaleType="center"
+        android:contentDescription="@*android:string/media_route_controller_disconnect"
         android:src="@drawable/ic_qs_cancel" />
 
 </LinearLayout>
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/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
new file mode 100644
index 0000000..603ebbf
--- /dev/null
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -0,0 +1,41 @@
+<?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"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+     <TextView android:id="@+id/tile_label"
+             android:layout_width="wrap_content"
+             android:layout_height="wrap_content"
+             android:textColor="@color/qs_tile_text"
+             android:gravity="center_horizontal"
+             android:minLines="2"
+             android:padding="0dp"
+             android:fontFamily="sans-serif-condensed"
+             android:textStyle="normal"
+             android:textSize="@dimen/qs_tile_text_size"
+             android:clickable="false" />
+     <ImageView android:id="@+id/restricted_padlock"
+             android:layout_width="@dimen/qs_tile_text_size"
+             android:layout_height="@dimen/qs_tile_text_size"
+             android:src="@drawable/ic_settings_lock_outline"
+             android:layout_marginLeft="@dimen/restricted_padlock_pading"
+             android:baselineAlignBottom="true"
+             android:scaleType="centerInside"
+             android:visibility="gone" />
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_user_detail_item.xml b/packages/SystemUI/res/layout/qs_user_detail_item.xml
index af22f03..a22c360 100644
--- a/packages/SystemUI/res/layout/qs_user_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_user_detail_item.xml
@@ -40,12 +40,25 @@
             systemui:framePadding="6dp"
             systemui:activeFrameColor="@color/current_user_border_color"/>
 
-    <TextView
-            android:id="@+id/user_name"
+    <LinearLayout
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textSize="@dimen/qs_detail_item_secondary_text_size"
-            android:textColor="@color/qs_user_detail_name"
-            android:gravity="center_horizontal" />
+            android:layout_height="wrap_content">
+        <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:textColor="@color/qs_user_detail_name"
+                android:gravity="center_horizontal" />
+        <ImageView
+                android:id="@+id/restricted_padlock"
+                android:layout_width="@dimen/qs_detail_item_secondary_text_size"
+                android:layout_height="@dimen/qs_detail_item_secondary_text_size"
+                android:src="@drawable/ic_settings_lock_outline"
+                android:layout_marginLeft="@dimen/restricted_padlock_pading"
+                android:baselineAlignBottom="true"
+                android:scaleType="centerInside"
+                android:visibility="gone" />
+    </LinearLayout>
 
 </com.android.systemui.qs.tiles.UserDetailItemView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 5b44c17..c813818 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -37,7 +37,8 @@
             android:translationZ="4dp"
             android:contentDescription="@string/recents_lock_to_app_button_label"
             android:background="@drawable/recents_lock_to_task_button_bg"
-            android:visibility="invisible">
+            android:visibility="invisible"
+            android:alpha="0">
             <ImageView
                 android:layout_width="@dimen/recents_lock_to_app_icon_size"
                 android:layout_height="@dimen/recents_lock_to_app_icon_size"
diff --git a/packages/SystemUI/res/layout/recents_task_view_header.xml b/packages/SystemUI/res/layout/recents_task_view_header.xml
index 04f18c5..07ac39a 100644
--- a/packages/SystemUI/res/layout/recents_task_view_header.xml
+++ b/packages/SystemUI/res/layout/recents_task_view_header.xml
@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!--
+     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.
@@ -63,4 +64,12 @@
         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" />
 </com.android.systemui.recents.views.TaskViewHeader>
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index 83cfc76..cce07bd 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -23,16 +23,16 @@
         android:id="@+id/remote_input"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
-        android:paddingStart="16dp"
-        android:paddingEnd="12dp"
-        android:paddingBottom="4dp"
-        android:paddingTop="2dp">
+        android:paddingEnd="12dp">
 
     <view class="com.android.systemui.statusbar.policy.RemoteInputView$RemoteEditText"
             android:id="@+id/remote_input_text"
             android:layout_height="match_parent"
             android:layout_width="0dp"
             android:layout_weight="1"
+            android:paddingTop="2dp"
+            android:paddingBottom="4dp"
+            android:paddingStart="16dp"
             android:paddingEnd="12dp"
             android:gravity="start|center_vertical"
             android:textAppearance="?android:attr/textAppearance"
@@ -47,7 +47,9 @@
     <FrameLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical">
+            android:layout_gravity="center_vertical"
+            android:paddingTop="2dp"
+            android:paddingBottom="4dp">
 
         <ImageButton
                 android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index aaa5a09..bea9f78 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -47,34 +47,14 @@
         android:orientation="horizontal"
         >
 
+        <!-- The alpha of this area is controlled from both PhoneStatusBarTransitions and
+             PhoneStatusBar (DISABLE_NOTIFICATION_ICONS). -->
         <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
             android:id="@+id/notification_icon_area"
             android:layout_width="0dip"
             android:layout_height="match_parent"
             android:layout_weight="1"
-            android:orientation="horizontal"
-            >
-            <!-- The alpha of this area is both controlled from PhoneStatusBarTransitions and
-                 PhoneStatusBar (DISABLE_NOTIFICATION_ICONS), so we need two views here. -->
-            <com.android.keyguard.AlphaOptimizedLinearLayout
-                android:id="@+id/notification_icon_area_inner"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                >
-                <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon"
-                    android:layout_width="@dimen/status_bar_icon_size"
-                    android:layout_height="match_parent"
-                    android:src="@drawable/stat_notify_more"
-                    android:visibility="gone"
-                    />
-                <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:layout_alignParentStart="true"
-                    android:gravity="center_vertical"
-                    android:orientation="horizontal"/>
-            </com.android.keyguard.AlphaOptimizedLinearLayout>
-        </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
+            android:orientation="horizontal" />
 
         <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/system_icon_area"
             android:layout_width="wrap_content"
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/layout/tv_pip_menu.xml b/packages/SystemUI/res/layout/tv_pip_menu.xml
new file mode 100644
index 0000000..a638d17
--- /dev/null
+++ b/packages/SystemUI/res/layout/tv_pip_menu.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <FrameLayout
+        android:layout_alignParentEnd="true"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:paddingStart="10dp"
+        android:paddingEnd="10dp"
+        android:background="#88FFFFFF">
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_gravity="center_vertical"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" >
+
+            <Button android:id="@+id/full"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:text="@string/pip_fullscreen"
+                android:textSize="10sp"
+                android:focusable="true" />
+
+            <Button android:id="@+id/exit"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:text="@string/pip_exit"
+                android:textSize="10sp"
+                android:focusable="true" />
+
+            <Button android:id="@+id/cancel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:text="@string/pip_cancel"
+                android:textSize="10sp"
+                android:focusable="true" />
+        </LinearLayout>
+    </FrameLayout>
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/tv_pip_overlay.xml b/packages/SystemUI/res/layout/tv_pip_overlay.xml
new file mode 100644
index 0000000..e8691b5
--- /dev/null
+++ b/packages/SystemUI/res/layout/tv_pip_overlay.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <TextView
+        android:id="@+id/guide_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:padding="3dp"
+        android:textSize="13sp"
+        android:textColor="#111111"
+        android:background="#99EEEEEE"
+        android:text="@string/pip_hold_home" />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 7617ed4..7cbc55c 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -46,6 +46,9 @@
         <!-- volume rows added and removed here! :-) -->
 
         <include layout="@layout/volume_zen_footer" />
+
+        <!-- Only shown from Tuner setting -->
+        <include layout="@layout/zen_mode_panel" />
     </LinearLayout>
 
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 0187993..cb68c9d 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Pas toe"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bevestig instellings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Sommige kleurinstellings kan hierdie toestel onbruikbaar maak. Klik OK om hierdie kleurinstellings te bevestig; andersins sal hierdie instellings ná 10 sekondes teruggestel word."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterybespaarder is nie beskikbaar wanneer gelaai word nie"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterybespaarder"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Verminder werkverrigting en agtergronddata"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Stelsel"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Tuis"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Onlangs"</string>
+    <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-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml
new file mode 100644
index 0000000..afb7fec
--- /dev/null
+++ b/packages/SystemUI/res/values-af/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">"Maak PIP toe"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Volskerm"</string>
+    <string name="pip_play" msgid="674145557658227044">"Speel"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Laat wag"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Kanselleer"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Hou HOME om PIP te beheer"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 503a767..4d44de7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"ተግብር"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ቅንብሮችን ያረጋግጡ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"አንዳንድ የቀለም ቅንብሮች ይህን መሣሪያ የማይጠቅም ሊያደርጉት ይችላሉ። እነዚህን የቀለም ቅንብሮች ለማረጋገጥ እሺ የሚለውን ጠቅ ያድርጉ፣ አለበለዚያ እነዚህ ቅንብሮች ከ10 ሰከንዶች በኋላ ዳግም ይጀምራሉ።"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ባትሪ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ኃይል በሚሞላበት ጊዜ ባትሪ ቆጣቢ አይገኝም"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ባትሪ ቆጣቢ"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"አፈጻጸምን እና የጀርባ ውሂብን ይቀንሳል"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ሥርዓት"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"መነሻ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"የቅርብ ጊዜዎቹ"</string>
+    <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 d89d036..f7128e4 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -476,4 +479,22 @@
     <string name="color_apply" msgid="9212602012641034283">"تطبيق"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"تأكيد الإعدادات"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"يمكن أن تتسبب بعض إعدادات الألوان في تعطيل إمكانية استخدام الجهاز. يمكنك النقر على \"موافق\" لتأكيد إعدادات الألوان هذه، وإلا فستتم إعادة تعيين هذه الإعدادات بعد 10 ثوانٍ."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"البطارية (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"وضع توفير شحن البطارية غير متاح أثناء الشحن."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"توفير شحن البطارية"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"لخفض مستوى الأداء وبيانات الخلفية"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"النظام"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"الشاشة الرئيسية"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"الأحدث"</string>
+    <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-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml
new file mode 100644
index 0000000..28329d5
--- /dev/null
+++ b/packages/SystemUI/res/values-ar/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-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 55f0841..71ced7c 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Tətbiq edin"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Ayarları təsdiq edin"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bəzi renk ayarları bu cihazı yararsız edə bilər. Bu rənk ayarlarını təsdiq etmək üçün OK basın, əks halda bu ayarlar 10 saniyə sonra sıfırlanacaq."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Enerji (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Enerji Qənaəti doldurulma zamanı əlçatan deyil"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Enerji Qənaəti"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı azaldır və arxa fon datasını məhdudlaşdırır"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Əsas səhifə"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Sonuncular"</string>
+    <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-az-rAZ/strings_tv.xml b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
new file mode 100644
index 0000000..8f3be27
--- /dev/null
+++ b/packages/SystemUI/res/values-az-rAZ/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 bağlayın"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string>
+    <string name="pip_play" msgid="674145557658227044">"Göstərin"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Fasilə verin"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Ləğv edin"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP idarə etmək üçün ƏSAS düyməni basıb saxlayın"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 4056963..fd98abc 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -473,4 +476,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Primeni"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potvrdite podešavanja"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Neka podešavanja boja mogu da učine uređaj neupotrebljivim. Kliknite na Potvrdi da biste potvrdili ova podešavanja boja, pošto će se u suprotnom ova podešavanja resetovati nakon 10 sekundi."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Baterija (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije nije dostupna tokom punjenja"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje performanse i pozadinske podatke"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni sadržaj"</string>
+    <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 93c26a4..e8f7f23 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Прилагане"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Потвърждаване на настройките"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Някои настройки за цветовете могат да направят това устройство неизползваемо. За да ги потвърдите, кликнете върху „OK“. В противен случай те ще бъдат нулирани след 10 секунди."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Батерия (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режимът за запазване на батерията не е налице при зареждане"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим за запазване на батерията"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Намалява ефективността и данните на заден план"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Системни"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Начало"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Скорошни"</string>
+    <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 939465b6..a49ab40 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"প্রয়োগ করুন"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"সেটিংস নিশ্চিত করুন"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"কিছু রঙের সেটিংস এই ডিভাইসকে ব্যবহারের অযোগ্য করে দিতে পারে৷ এই রঙের সেটিংস নিশ্চিত করতে ওকে এ ক্লিক করুন, অন্যথায় ১০ সেকেন্ড পরে এই সেটিংস পুনরায় সেট হবে৷"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ব্যাটারি (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"চার্জ করার সময় ব্যাটারি সেভার উপলব্ধ নয়"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ব্যাটারি সেভার"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"কার্য-সম্পাদনা ও পশ্চাদপট ডেটাকে কমিয়ে দেয়"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"সিস্টেম"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"হোম"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"সাম্প্রতিকগুলি"</string>
+    <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 e19aa0e..0fce766 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplica"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirma la configuració"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunes opcions de configuració de color poden deixar el dispositiu inservible. Fes clic a D\'acord per confirmar la configuració de color; en cas contrari, la configuració es restablirà al cap de 10 segons."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"La funció Estalvi de bateria no està disponible durant la càrrega"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Estalvi de bateria"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Redueix el rendiment i les dades en segon pla"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inici"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recents"</string>
+    <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 b1cd561..6fff76b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Použít"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Ověření nastavení"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Některá nastavení barev mohou způsobit, že zařízení nebude použitelné. Kliknutím na OK toto nastavení barev potvrdíte, v opačném případě se nastavení po 10 sekundách resetuje."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Baterie (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Spořič baterie při nabíjení není k dispozici."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Spořič baterie"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omezuje výkon a data na pozadí"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systém"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Plocha"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Poslední"</string>
+    <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 2100c57..2941927 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Anvend"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bekræft indstillingerne"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Nogle farveindstillinger kan medføre, at du ikke kan bruge enheden. Klik på OK for at bekræfte disse farveindstillinger. Ellers nulstilles disse indstillinger efter ti sekunder."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batteri (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparefunktionen er ikke tilgængelig under opladning"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparefunktion"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reducerer ydeevne og baggrundsdata"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Start"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Seneste"</string>
+    <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 1ad5b26..9afa618 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -23,7 +23,7 @@
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Löschen"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Aus Liste entfernen"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-Info"</string>
-    <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Hier sehen Sie Ihre zuletzt geöffneten Apps."</string>
+    <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Hier siehst du deine zuletzt geöffneten Apps."</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Kürzlich geöffnete Apps schließen"</string>
     <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
       <item quantity="other">%d Bildschirme in der Übersicht</item>
@@ -35,9 +35,9 @@
     <string name="battery_low_title" msgid="6456385927409742437">"Akku ist schwach"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend"</string>
     <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend. Der Energiesparmodus ist aktiviert."</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt.\nVerwenden Sie das mitgelieferte Aufladegerät."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt.\nVerwende das mitgelieferte Aufladegerät."</string>
     <string name="invalid_charger_title" msgid="3515740382572798460">"Laden per USB wird nicht unterstützt."</string>
-    <string name="invalid_charger_text" msgid="5474997287953892710">"Verwenden Sie nur das im Lieferumfang enthaltene Ladegerät."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Verwende nur das im Lieferumfang enthaltene Ladegerät."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Einstellungen"</string>
     <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Energiesparmodus aktivieren?"</string>
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Aktivieren"</string>
@@ -64,7 +64,7 @@
     <string name="usb_debugging_message" msgid="2220143855912376496">"Der Fingerabdruck des RSA-Schlüssels für diesen Computer lautet: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Von diesem Computer immer zulassen"</string>
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-Debugging nicht zulässig"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Wechseln Sie zu einem Administratorkonto, um diese Funktion nutzen zu können."</string>
+    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Wechsle zu einem Administratorkonto, um diese Funktion nutzen zu können."</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom auf Bildschirmgröße"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Auf Bildschirmgröße anpassen"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Screenshot wird gespeichert..."</string>
@@ -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>
@@ -222,7 +222,7 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-Daten pausiert"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobilfunkdaten pausiert"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Daten pausiert"</string>
-    <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Da Ihr festgelegtes Datenlimit erreicht wurde, hat das Gerät die Datennutzung für den Rest dieses Zeitraums pausiert.\n\nWenn Sie diese fortsetzen, können möglicherweise Kosten bei Ihrem Mobilfunkanbieter entstehen."</string>
+    <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Da dein festgelegtes Datenlimit erreicht wurde, hat das Gerät die Datennutzung für den Rest dieses Zeitraums pausiert.\n\nWenn du die Nutzung fortsetzt, entstehen möglicherweise Kosten bei deinem Mobilfunkanbieter."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Fortsetzen"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Keine Internetverbindung"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN verbunden"</string>
@@ -295,7 +295,7 @@
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> Datenlimit"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Warnung für <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Arbeitsmodus"</string>
-    <string name="recents_empty_message" msgid="8682129509540827999">"Hier sehen Sie Ihre zuletzt geöffneten Apps."</string>
+    <string name="recents_empty_message" msgid="8682129509540827999">"Hier siehst du deine zuletzt geöffneten Apps."</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"App-Info"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Bildschirmfixierung"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
@@ -313,9 +313,9 @@
     <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
-    <string name="zen_priority_introduction" msgid="3070506961866919502">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von Ihnen festgelegten Personen."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von dir festgelegten Personen."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassen"</string>
-    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele. Anrufe können Sie jedoch weiterhin tätigen."</string>
+    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele. Anrufe kannst du jedoch weiterhin tätigen."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele."</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</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>
@@ -347,7 +350,7 @@
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Entfernen"</string>
     <string name="guest_wipe_session_title" msgid="6419439912885956132">"Willkommen zurück im Gastmodus"</string>
-    <string name="guest_wipe_session_message" msgid="8476238178270112811">"Möchten Sie Ihre Sitzung fortsetzen?"</string>
+    <string name="guest_wipe_session_message" msgid="8476238178270112811">"Möchtest du deine Sitzung fortsetzen?"</string>
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Von vorn"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Ja, weiter"</string>
     <string name="guest_notification_title" msgid="1585278533840603063">"Gastnutzer"</string>
@@ -357,14 +360,14 @@
     <string name="user_logout_notification_text" msgid="3350262809611876284">"Aktuellen Nutzer abmelden"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"Nutzer abmelden"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"Neuen Nutzer hinzufügen?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"Wenn Sie einen neuen Nutzer hinzufügen, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
     <string name="user_remove_user_title" msgid="4681256956076895559">"Nutzer entfernen?"</string>
     <string name="user_remove_user_message" msgid="1453218013959498039">"Alle Apps und Daten dieses Nutzers werden gelöscht."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"Entfernen"</string>
     <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>
@@ -377,17 +380,17 @@
     <string name="monitoring_title" msgid="169206259253048106">"Netzwerküberwachung"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"VPN deaktivieren"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN-Verbindung trennen"</string>
-    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Ihr Gerät wird verwaltet von <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nIhr Administrator kann die zu Ihrem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen Ihres Geräts. Weitere Informationen erhalten Sie bei Ihrem Administrator."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Sie haben einer App gestattet, eine VPN-Verbindung einzurichten.\n\nDiese App kann Ihr Gerät und Ihre Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites."</string>
-    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Ihr Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nIhr Administrator kann die zu Ihrem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen Ihres Geräts.\n\nSie sind zudem mit einem VPN verbunden, das Ihre persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie bei Ihrem Administrator."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Ihr Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nIhr Administrator kann Ihre Netzwerkaktivität überwachen, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie bei Ihrem Administrator.\n\nSie sind zudem mit einem VPN verbunden, das Ihre persönliche Netzwerkaktivität überwachen kann."</string>
+    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Dein Gerät wird verwaltet von <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nDein Administrator kann die zu deinem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen deines Geräts. Weitere Informationen erhältst du bei deinem Administrator."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Du hast einer App gestattet, eine VPN-Verbindung einzurichten.\n\nDiese App kann dein Gerät und deine Netzwerkaktivitäten überwachen, einschließlich E-Mails, Apps und Websites."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Dein Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann die zu deinem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen deines Geräts.\n\nDu bist außerdem mit einem VPN verbunden, das deine persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du bei deinem Administrator."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann deine Netzwerkaktivität überwachen, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du bei deinem Administrator.\n\nDu bist außerdem mit einem VPN verbunden, das deine persönliche Netzwerkaktivität überwachen kann."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="6259179342284742878">"Sie sind mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die Ihre Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
-    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Sie sind mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die Ihre persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
-    <string name="monitoring_description_app_work" msgid="1754325860918060897">"Ihr Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die Ihre geschäftlichen Netzwerkaktivitäten überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie von Ihrem Administrator."</string>
-    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Ihr Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> verbunden, die Ihre geschäftliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nSie sind außerdem mit der App <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> verbunden, die Ihre persönliche Netzwerkaktivität überwachen kann."</string>
-    <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Ihr Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nIhr Administrator kann die zu Ihrem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen Ihres Geräts.\n\nSie sind mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die Ihre persönlichen Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhalten Sie bei Ihrem Administrator."</string>
-    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Das Gerät bleibt gesperrt, bis Sie es manuell entsperren."</string>
+    <string name="monitoring_description_app" msgid="6259179342284742878">"Du bist mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die deine Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
+    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Du bist mit der App <xliff:g id="APPLICATION">%1$s</xliff:g> verbunden, die deine persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites."</string>
+    <string name="monitoring_description_app_work" msgid="1754325860918060897">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die deine geschäftlichen Netzwerkaktivitäten überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du von deinem Administrator."</string>
+    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Dein Arbeitsprofil wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet. Das Profil ist mit der App <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> verbunden, die deine geschäftliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nDu bist außerdem mit der App <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> verbunden, die deine persönliche Netzwerkaktivität überwachen kann."</string>
+    <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Dein Gerät wird von <xliff:g id="ORGANIZATION">%1$s</xliff:g> verwaltet.\n\nDein Administrator kann die zu deinem Gerät gehörigen Einstellungen, Unternehmenszugriffsrechte, Apps und Daten überwachen und verwalten, einschließlich der Standortinformationen deines Geräts.\n\nDu bist außerdem mit der App <xliff:g id="APPLICATION">%2$s</xliff:g> verbunden, die deine persönliche Netzwerkaktivität überwachen kann, einschließlich E-Mails, Apps und Websites.\n\nWeitere Informationen erhältst du bei deinem Administrator."</string>
+    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Das Gerät bleibt gesperrt, bis du es manuell entsperrst."</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Benachrichtigungen schneller erhalten"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Vor dem Entsperren anzeigen"</string>
     <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nein danke"</string>
@@ -397,11 +400,11 @@
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Maximieren"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minimieren"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
-    <string name="screen_pinning_description" msgid="3577937698406151604">"Der Bildschirm wird solange angezeigt, bis Sie die Fixierung aufheben. Berühren und halten Sie \"Zurück\", wenn Sie die Fixierung aufheben möchten."</string>
+    <string name="screen_pinning_description" msgid="3577937698406151604">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte \"Zurück\", wenn du die Fixierung aufheben möchtest."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ausblenden?"</string>
-    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn Sie sie in den Einstellungen erneut aktivieren."</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn du sie in den Einstellungen erneut aktivierst."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ausblenden"</string>
     <string name="volumeui_prompt_message" msgid="918680947433389110">"<xliff:g id="APP_NAME">%1$s</xliff:g> will die Lautstärke regeln."</string>
     <string name="volumeui_prompt_allow" msgid="7954396902482228786">"Zulassen"</string>
@@ -409,7 +412,7 @@
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> regelt die Lautstärke."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Zum Wiederherstellen des Originals hier tippen"</string>
     <string name="group_summary_concadenation" msgid="6846402378100148789">"\", \" "</string>
-    <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Sie verwenden Ihr Arbeitsprofil."</string>
+    <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du verwendest dein Arbeitsprofil."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Eingebettete Akku-Prozentzahl anzeigen"</string>
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prozentzahl für Akkustand in Statusleistensymbol anzeigen, wenn das Gerät nicht geladen wird"</string>
@@ -425,7 +428,7 @@
     <string name="status_bar_airplane" msgid="7057575501472249002">"Flugmodus"</string>
     <string name="add_tile" msgid="2995389510240786221">"Kachel hinzufügen"</string>
     <string name="broadcast_tile" msgid="3894036511763289383">"Broadcast-Kachel"</string>
-    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Sie erhalten einen lautlosen Weckruf <xliff:g id="WHEN">%1$s</xliff:g>, wenn Sie ihn nicht vorher ausschalten."</string>
+    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Du erhältst einen lautlosen Weckruf <xliff:g id="WHEN">%1$s</xliff:g>, wenn du ihn nicht vorher ausschaltest."</string>
     <string name="zen_alarm_warning" msgid="444533119582244293">"Lautloser Weckruf <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template" msgid="3980063409350522735">"um <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"am <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -433,13 +436,13 @@
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Arbeitsprofil"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Für einige ein Vergnügen, aber nicht für alle"</string>
-    <string name="tuner_warning" msgid="8730648121973575701">"Mit System UI Tuner erhalten Sie zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"Mit System UI Tuner erhältst du zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
     <string name="got_it" msgid="2239653834387972602">"OK"</string>
     <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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Übernehmen"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Einstellungen bestätigen"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Einige Farbeinstellungen können dazu führen, dass das Gerät nicht mehr genutzt werden kann. Klicke auf \"OK\", um diese Farbeinstellungen zu bestätigen. Anderenfalls werden diese Einstellungen in 10 Sekunden zurückgesetzt."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Akku (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Der Energiesparmodus ist beim Aufladen nicht verfügbar."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Energiesparmodus"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduzierung der Leistung und Hintergrunddaten"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startseite"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Letzte"</string>
+    <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 f56d630..f128544 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Εφαρμογή"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Επιβεβαίωση ρυθμίσεων"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Ορισμένες ρυθμίσεις χρωμάτων μπορεί να μην επιτρέπουν τη χρήση αυτής της συσκευής. Κάντε κλικ στην επιλογή OK για να επιβεβαιώσετε αυτές τις ρυθμίσεις χρωμάτων, διαφορετικά θα γίνει επαναφορά αυτών των ρυθμίσεων μετά από 10 δευτερόλεπτα."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Μπαταρία (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Η εξοικονόμηση μπαταρίας δεν είναι διαθέσιμη κατά τη διάρκεια της φόρτισης"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Εξοικονόμηση μπαταρίας"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Μειώνει την απόδοση και τα δεδομένα παρασκηνίου"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Σύστημα"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Αρχική οθόνη"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Πρόσφατα"</string>
+    <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 f6fc997..38f3d38 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Apply"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirm Settings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Some colour settings can make this device unusable. Click OK to confirm these colour settings, otherwise these settings will reset after 10 seconds."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
+    <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-rAU/strings_tv.xml b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
new file mode 100644
index 0000000..76576dd
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rAU/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">"Close PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
+    <string name="pip_play" msgid="674145557658227044">"Play"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pause"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancel"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Hold HOME to control PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index f6fc997..38f3d38 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Apply"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirm Settings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Some colour settings can make this device unusable. Click OK to confirm these colour settings, otherwise these settings will reset after 10 seconds."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
+    <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_tv.xml b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
new file mode 100644
index 0000000..76576dd
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rGB/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">"Close PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
+    <string name="pip_play" msgid="674145557658227044">"Play"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pause"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancel"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Hold HOME to control PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index f6fc997..38f3d38 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Apply"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirm Settings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Some colour settings can make this device unusable. Click OK to confirm these colour settings, otherwise these settings will reset after 10 seconds."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
+    <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_tv.xml b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
new file mode 100644
index 0000000..76576dd
--- /dev/null
+++ b/packages/SystemUI/res/values-en-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">"Close PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
+    <string name="pip_play" msgid="674145557658227044">"Play"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pause"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancel"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Hold HOME to control PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index fd59418..c521912 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar la configuración"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunas opciones de configuración de color pueden provocar que el dispositivo quede inutilizable. Haz clic en Aceptar para confirmar estos parámetros de color. De lo contrario, la configuración se restablecerá en diez segundos."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batería (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no está disponible durante la carga"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y el uso de datos en segundo plano"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pantalla principal"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
+    <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 223e684..8d98049 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configuración"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunas opciones de configuración de color pueden hacer que el dispositivo no se pueda utilizar. Haz clic en Aceptar para confirmar esta configuración. Si no lo haces, se restablecerá esta configuración cuando transcurran 10 segundos."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batería (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no disponible mientras se carga el dispositivo"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y las conexiones automáticas"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
+    <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 f50e78c..126bc12 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Rakenda"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Seadete kinnitamine"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Mõni värviseade ei saa seadet võib-olla kasutada. Nende värviseadete kinnitamiseks klõpsake OK, muidu lähtestatakse need seaded 10 sekundi pärast."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Aku (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akusäästja pole laadimise ajal saadaval"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akusäästja"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vähendab jõudlust ja taustaandmeid"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Süsteem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Avaekraan"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Hiljutised"</string>
+    <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 c481f52..54154ea 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplikatu"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Berretsi ezarpenak"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Baliteke gailua kolore-ezarpen batzuekin ezin erabili izatea. Kolore-ezarpenak berresteko, sakatu Ados. Bestela, hamar segundoren buruan berrezarriko dira ezarpenak."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (%% <xliff:g id="ID_1">%1$d</xliff:g>)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Bateria-aurrezlea ez dago erabilgarri gailua kargatzen ari denean"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Bateria-aurrezlea"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Errendimendua eta atzeko planoko datuen erabilera murrizten ditu"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Hasierako pantaila"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Azkenak"</string>
+    <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 3dee7c9..da13225 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"اعمال‌ کردن"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"تأیید تنظیمات"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"بعضی از تنظیمات رنگ می‌توانند این دستگاه را غیرقابل استفاده کنند. برای تأیید این تنظیمات رنگ روی «تأیید» کلیک کنید، در غیر این صورت این تغییرات بعد از ۱۰ ثانیه بازنشانی می‌شوند."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"باتری (<xliff:g id="ID_1">%1$d</xliff:g>٪٪)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"هنگام شارژ شدن، «بهینه‌سازی باتری» در دسترس نیست"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"بهینه‌سازی باتری"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"عملکرد و اطلاعات پس‌زمینه را کاهش می‌دهد"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"سیستم"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"صفحه اصلی"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"موارد اخیر"</string>
+    <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 4a5c302..8e89737 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Käytä"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Vahvista asetukset"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Jotkin väriasetukset voivat häiritä laitteen käyttöä. Vahvista uudet väriasetukset valitsemalla OK. Muussa tapauksessa aiemmat asetukset palautetaan 10 sekunnin kuluttua."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Akku (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Virransäästö ei ole käytettävissä latauksen aikana."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Virransäästö"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Rajoittaa suorituskykyä ja taustatiedonsiirtoa."</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Järjestelmä"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Aloitusnäyttö"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Viimeaikaiset"</string>
+    <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 2a4f4d9..b61a260 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Appliquer"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmer les paramètres"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Certains paramètres de couleurs peuvent rendre cet appareil inutilisable. Cliquez sur « OK » pour valider ces paramètres, sinon ils seront réinitialisés après 10 secondes."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Pile (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Le mode Économie d\'énergie n\'est pas accessible pendant la charge"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économie d\'énergie"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Réduit les performances et les données en arrière-plan"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Système"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
+    <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 928a8b3..3d02297 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Appliquer"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Vérifier les paramètres"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Certains paramètres de couleurs peuvent rendre cet appareil inutilisable. Cliquez sur \"OK\" pour valider ces paramètres, sans quoi ils seront réinitialisés après 10 secondes."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batterie (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"L\'économiseur de batterie n\'est pas disponible lorsque l\'appareil est en charge."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économiseur de batterie"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Limite les performances et les données en arrière-plan."</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Système"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
+    <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 2a951f7..b69219b 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configuración"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunhas opcións de configuración de cor poden facer que este dispositivo sexa inutilizable. Fai clic en Aceptar para confirmar esta configuración de cor; en caso contrario, a configuración restablecerase tras 10 segundos."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batería (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A función aforro de batería non está dispoñible durante a carga"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Aforro de batería"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce o rendemento e os datos en segundo plano"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
+    <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 f331ef9..1211e7b 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"લાગુ કરો"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"સેટિંગ્સની પુષ્ટિ કરો"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"કેટલીક રંગ સેટિંગ્સ આ ઉપકરણને બિનઉપયોગી બનાવી શકે છે. આ રંગ સેટિંગ્સની પુષ્ટિ કરવા માટે ઑકે ક્લિક કરો, અન્યથા 10 સેકંડ પછી આ સેટિંગ્સ ફરીથી સેટ થશે."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"બૅટરી (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ચાર્જિંગ દરમિયાન બૅટરી બચતકર્તા ઉપલબ્ધ નથી"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"બૅટરી બચતકર્તા"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"પ્રદર્શન અને પૃષ્ઠભૂમિ ડેટા ઘટાડે છે"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"સિસ્ટમ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"હોમ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"તાજેતરના"</string>
+    <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-gu-rIN/strings_tv.xml b/packages/SystemUI/res/values-gu-rIN/strings_tv.xml
new file mode 100644
index 0000000..fbb9a4f
--- /dev/null
+++ b/packages/SystemUI/res/values-gu-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-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index b31c1e0..7e70dee 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"लागू करें"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"से‍ेटिंग की पुष्टि करें"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"कुछ रंग सेटिंग इस डिवाइस को अनुपयोगी बना सकती हैं. इन रंग सेटिंग की पुष्टि करने के लिए ठीक क्लिक करें, अन्यथा 10 सेकंड के बाद ये सेटिंग रीसेट हो जाएंगी."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"बैटरी (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज किए जाने के दौरान बैटरी सेवर उपलब्ध नहीं है"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"बैटरी सेवर"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"निष्‍पादन और पृष्ठभूमि डेटा को कम करता है"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टम"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हाल ही के"</string>
+    <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-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml
new file mode 100644
index 0000000..780725d
--- /dev/null
+++ b/packages/SystemUI/res/values-hi/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-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 3bef6e9..23cb96b 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -473,4 +476,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Primijeni"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potvrdite postavke"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Neke postavke boja mogu učiniti uređaj neupotrebljivim. Kliknite U redu da biste potvrdili postavke boja jer će se u suprotnom poništiti za 10 sekundi."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Baterija (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Štednja baterije nije dostupna tijekom punjenja"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Štednja baterije"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje količinu rada i pozadinske podatke"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sustav"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni zaslon"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Najnovije"</string>
+    <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 8dc9a19..84454f6 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Alkalmaz"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Beállítások megerősítése"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bizonyos színbeállítások használhatatlanná tehetik ezt az eszközt. A színbeállítás megerősítéséhez kattintson az OK lehetőségre, máskülönben a rendszer 10 másodpercen belül visszaáll a korábbira."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Akkumulátor (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Az Akkumulátorkímélő módot töltés közben nem lehet használni"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akkumulátorkímélő mód"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Csökkenti a teljesítményt és a háttéradatok használatát"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Rendszer"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Otthon"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Legutóbbiak"</string>
+    <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-hu/strings_tv.xml b/packages/SystemUI/res/values-hu/strings_tv.xml
new file mode 100644
index 0000000..73ba98d
--- /dev/null
+++ b/packages/SystemUI/res/values-hu/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">"Kép a képben (PIP) bezárása"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Teljes képernyő"</string>
+    <string name="pip_play" msgid="674145557658227044">"Lejátszás"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Szüneteltetés"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Mégse"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Tartsa nyomva a KEZDŐKÉPERNYŐ gombot a PIP funkció vezérléséhez"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 99d6980..89045e1 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -433,12 +436,12 @@
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Թեժ կետ"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Աշխատանքային պրոֆիլ"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string>
-    <string name="tuner_warning" msgid="8730648121973575701">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտվողի միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"Համակարգի ՕՄ-ի ընդունիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտվողի միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
     <string name="got_it" msgid="2239653834387972602">"Հասկանալի է"</string>
-    <string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի կարգավորիչը ավելացվել է կարգավորումներին"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի ընդունիչը ավելացվել է կարգավորումներին"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Հեռացնել կարգավորումներից"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի կարգավորիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի ընդունիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string>
     <string name="activity_not_found" msgid="348423244327799974">"Հավելվածը տեղադրված չէ սարքի վրա"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Ցույց տալ ժամացույցի վայրկյանները"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Ցույց տալ ժամացույցի վայրկյանները կարգավիճակի տողում: Կարող է ազդել մարտկոցի աշխատանքի ժամանակի վրա:"</string>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Կիրառել"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Հաստատել կարգավորումները"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Գունային որոշ կարգավորումները կարող են այս սարքը օգտագործման համար ոչ պիտանի դարձնել: Սեղմեք Լավ կոճակը՝ գունային այս կարգավորումները հաստատելու համար: Հակառակ դեպքում այս կարգավորումները կվերակայվեն 10 վայրկյան հետո:"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Մարտկոց (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Մարտկոցի տնտեսումը լիցքավորման ժամանակ հասանելի չէ"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Մարտկոցի տնտեսում"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Նվազեցնում է ծանրաբեռնվածությունը և ֆոնային տվյալները"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Համակարգ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Գլխավոր էջ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Վերջինները"</string>
+    <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 f6124db..b7ac86d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Terapkan"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Konfirmasi setelan"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Beberapa setelan warna dapat membuat perangkat ini tidak dapat digunakan. Klik OKE untuk mengonfirmasi setelan warna ini. Jika tidak, setelan ini akan disetel ulang setelah 10 detik."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Baterai (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penghemat Baterai tidak tersedia selama pengisian daya"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penghemat Baterai"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangi performa dan data latar belakang"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Layar Utama"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaru"</string>
+    <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-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml
new file mode 100644
index 0000000..b889231
--- /dev/null
+++ b/packages/SystemUI/res/values-in/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">"Layar penuh"</string>
+    <string name="pip_play" msgid="674145557658227044">"Putar"</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 LAYAR UTAMA untuk mengontrol PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 7ea1746..cb2a3bd 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Nota"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Staðfesta stillingar"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Sumar litastillingar kunna að bitna á notagildi tækisins. Veldu „Í lagi“ til að staðfesta þessar litastillingar, að öðrum kosti verða litirnir endurstilltir eftir tíu sekúndur."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Rafhlaða (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ekki er hægt að nota rafhlöðusparnað meðan á hleðslu stendur"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Rafhlöðusparnaður"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Dregur úr afköstum og bakgrunnsgögnum"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Kerfi"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Heim"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nýlegt"</string>
+    <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 b395f8b..998230d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Applica"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Conferma le impostazioni"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Alcune impostazioni relative ai colori potrebbero rendere inutilizzabile il dispositivo. Fai clic su OK per confermare queste impostazioni; in caso contrario, le impostazioni verranno reimpostate dopo 10 secondi."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batteria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Risparmio energetico non disponibile durante la ricarica"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Risparmio energetico"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Riduce le prestazioni e i dati in background"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recenti"</string>
+    <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-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml
new file mode 100644
index 0000000..0279e45
--- /dev/null
+++ b/packages/SystemUI/res/values-it/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">"Chiudi visualizzazione PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Schermo intero"</string>
+    <string name="pip_play" msgid="674145557658227044">"Riproduci"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausa"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Annulla"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Tieni premuto HOME per controllare la visualizzazione PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 2c894f5..af5edb4 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"החל"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"אישור הגדרות"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"הגדרות צבע מסוימות עלולות להפוך את המכשיר הזה לבלתי שמיש. לחץ על אישור כדי לאשר את הגדרות הצבע האלה, אחרת הגדרות אלה יתאפסו לאחר 10 שניות."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"סוללה (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"חיסכון בסוללה"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"מפחית את רמת הביצועים ואת נתוני הרקע"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"מערכת"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"דף הבית"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"אחרונים"</string>
+    <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 580d995..5f448bf 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"適用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"設定の確認"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"一部の色設定を適用すると、この端末を使用できなくなることがあります。この色設定を確認するには、[OK] をクリックしてください。確認しない場合、10 秒後に設定はリセットされます。"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"バッテリー(<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電中はバッテリー セーバーは利用できません"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"バッテリー セーバー"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"パフォーマンスとバックグラウンド データを制限します"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"システム"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ホーム"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
+    <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 7a51668..38fd4b3 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"გამოყენება"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"პარამეტრების დადასტურება"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ფერთა ზოგიერთ პარამეტრს ამ მოწყობილობასთან მუშაობის გართულება შეუძლია. ფერთა ამჟამინდელი პარამეტრების დასადასტურებლად, დააწკაპუნეთ „კარგი“-ზე. წინააღმდეგ შემთხვევაში, პარამეტრები 10 წამის შემდეგ ჩამოიყრება."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ბატარეა (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ბატარეის დამზოგი დატენვისას მიწვდომელია"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ბატარეის დამზოგი"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ამცირებს წარმადობას და ფონურ მონაცემებს"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"სისტემა"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"მთავარი"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ბოლოს გამოყენებული"</string>
+    <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 eb8995e..f1d96b2 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Қолдану"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Параметрлерді растау"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Кейбір түс параметрлері бұл құрылғыны пайдалану мүмкін емес етуі мүмкін. Бұл түс параметрлерін растау үшін OK түймесін басыңыз, әйтпесе параметрлер 10 секундтан кейін ысырылады."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Батарея (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Зарядтау кезінде Батарея үнемдегіш қол жетімді емес"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батарея үнемдегіш"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Өнімділікті және фондық деректерді азайтады"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Жүйе"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Негізгі бет"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Жақындағылар"</string>
+    <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-kk-rKZ/strings_tv.xml b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
new file mode 100644
index 0000000..6339f42
--- /dev/null
+++ b/packages/SystemUI/res/values-kk-rKZ/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-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 5c10213..7f5b0d8 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"អនុវត្ត"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"បញ្ជាក់ការកំណត់"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ការកំណត់ពណ៌មួយចំនួនអាចធ្វើឲ្យឧបករណ៍នេះមិនអាចប្រើបាន។ សូមចុច យល់ព្រម ដើម្បីបញ្ជាក់ការកំណត់ពណ៌ទាំងនេះ បើមិនដូច្នេះទេការកំណត់ទាំងនេះនឹងកំណត់ឡើងវិញក្នុងរយៈពេល 10 វិនាទីបន្ទាប់។"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ថ្ម (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"កម្មវិធីសន្សំថ្ម"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"កាត់បន្ថយប្រតិបត្តិការ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ប្រព័ន្ធ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ដើម"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ថ្មីៗ"</string>
+    <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_tv.xml b/packages/SystemUI/res/values-km-rKH/strings_tv.xml
new file mode 100644
index 0000000..6e6172c
--- /dev/null
+++ b/packages/SystemUI/res/values-km-rKH/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-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 28b2de5..e238e53 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"ಅನ್ವಯಿಸು"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಖಚಿತಪಡಿಸಿ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ಕೆಲವು ಬಣ್ಣ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಸಾಧನವನ್ನು ಅನುಪಯುಕ್ತಗೊಳಿಸಬಹುದು. ಈ ಬಣ್ಣ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಖಚಿತಪಡಿಸಲು ಸರಿ ಕ್ಲಿಕ್ ಮಾಡಿ, ಇಲ್ಲವಾದರೆ ಈ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು 10 ಸೆಕೆಂಡುಗಳ ನಂತರ ಮರುಹೊಂದಿಸಿ."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ಬ್ಯಾಟರಿ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ಚಾರ್ಜಿಂಗ್ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಸೇವರ್‌‌ ಲಭ್ಯವಿರುವುದಿಲ್ಲ"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ಬ್ಯಾಟರಿ ಸೇವರ್‌‌"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ಸಿಸ್ಟಂ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ಮುಖಪುಟ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ಇತ್ತೀಚಿನವುಗಳು"</string>
+    <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_tv.xml b/packages/SystemUI/res/values-kn-rIN/strings_tv.xml
new file mode 100644
index 0000000..c2a7095
--- /dev/null
+++ b/packages/SystemUI/res/values-kn-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-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 110376f..725bd18 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"적용"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"설정 확인"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"일부 색상 설정으로 인해 이 기기를 사용하지 못할 수 있습니다. 확인을 클릭하여 이러한 색상 설정을 확인하지 않으면 10초 후에 설정이 초기화됩니다."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"배터리(<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"충전하는 동안 배터리 세이버는 사용할 수 없습니다."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"배터리 세이버"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"성능 및 백그라운드 데이터를 줄입니다."</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"시스템"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"홈"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"최근"</string>
+    <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 ee2ef5d..539cc7e 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Колдонуу"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Жөндөөлөрдү ырастоо"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Айрым түс жөндөөлөрү бул түзмөктү колдонулгус кылып коюшу мүмкүн. Бул түс жөндөөлөрүн ырастоо үчүн OK баскычын чыкылдатыңыз, болбосо бул жөндөөлөр 10 секунддан кийин баштапкы абалына келтирилет."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Батарея (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Батареяны үнөмдөгүч түзмөк кубатталып жатканда иштебейт"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батареяны үнөмдөгүч"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Иштин майнаптуулугун начарлатып, фондук дайындарды чектейт"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Тутум"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Башкы бет"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Акыркылар"</string>
+    <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 ed103ea..b75e398 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"ນຳໃຊ້"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ຢືນ​ຢັນ​ການ​ຕັ້ງ​ຄ່າ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ບາງການຕັ້ງຄ່າສີສາມາດເຮັດໃຫ້ອຸປະກອນນີ້ບໍ່ສາມາດໃຊ້ໄດ້. ຄລິກ ຕົກລົງ ເພື່ອຢືນຢັນການຕັ້ງຄ່າສີເຫຼົ່ານີ້, ຖ້າບໍ່ດັ່ງນັ້ນ ການຕັ້ງຄ່າເຫຼົ່ານີ້ຈະຕັ້ງຄືນໃໝ່ ຫຼັງຈາກ 10 ວິນາທີ."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ແບັດເຕີຣີ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ຕົວປະຢັດແບັດເຕີຣີບໍ່ມີໃຫ້ນຳໃຊ້ໃນລະຫວ່າງການສາກ"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ຕົວປະຢັດ​ແບັດເຕີຣີ"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ຫຼຸດ​ປະ​ສິ​ທິ​ພາບ​ການໃຊ້ງານ ແລະ ​ຂໍ້​ມູນ​ພື້ນຫຼັງ"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ລະບົບ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"​ໜ້າຫຼັກ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ຫາ​ກໍ​ໃຊ້"</string>
+    <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 ba98e2b..e79e6d3 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Taikyti"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Nustatymų patvirtinimas"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Dėl kai kurių spalvų nustatymų įrenginys gali būti netinkamas naudoti. Spustelėkite „Gerai“, kad patvirtintumėte šiuos spalvų nustatymus. Kitaip šie nustatymai bus nustatyti iš naujo po 10 sekundžių."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Akumuliatorius (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumuliatoriaus tausojimo priemonė nepasiekiama įkraunant"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumuliatoriaus tausojimo priemonė"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sumažinamas našumas ir foninių duomenų naudojimas"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pagrindinis ekranas"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Naujausios veiklos ekranas"</string>
+    <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-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml
new file mode 100644
index 0000000..b9719c4
--- /dev/null
+++ b/packages/SystemUI/res/values-lt/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">"Uždaryti PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Visas ekranas"</string>
+    <string name="pip_play" msgid="674145557658227044">"Leisti"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pristabdyti"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Atšaukti"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Jei norite valdyti PIP, palaikykite paspaudę mygtuką HOME"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 0143fea..3b27424 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -473,4 +476,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Lietot"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Iestatījumu apstiprināšana"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Noteiktu krāsu iestatījumu dēļ šī ierīce var kļūt nelietojama. Lai apstiprinātu šos krāsu iestatījumus, noklikšķiniet uz Labi. Ja to neizdarīsiet, pēc 10 sekundēm šie iestatījumi tiks atiestatīti."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Akumulators (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumulatora jaudas taupīšanas režīms uzlādes laikā nav pieejams."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumulatora jaudas taupīšanas režīms"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Samazina veiktspēju un fona datus."</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistēma"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Sākums"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Pēdējie"</string>
+    <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 c573139..85832df 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Примени"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Потврдете ги поставките"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Некои поставки на боите може да го направат уредот неупотреблив. Кликнете на Во ред за да ги потврдите овие поставки на боите, инаку тие поставки ќе се ресетираат по 10 секунди."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Батерија (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Штедачот на батерија не е достапен при полнење"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Штедач на батерија"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ја намалува изведбата и податоците во заднина"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетна страница"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Неодамнешни"</string>
+    <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 c6a08e6..b2d7b9d 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"ബാധകമാക്കുക"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ക്രമീകരണം സ്ഥിരീകരിക്കുക"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ചില വർണ്ണ ക്രമീകരണത്തിന് ഈ ഉപകരണത്തെ ഉപയോഗരഹിതമാക്കാനാകും. ഈ വർണ്ണ ക്രമീകരണം സ്ഥിരീകരിക്കുന്നതിന് ശരി എന്നതിൽ ക്ലിക്കുചെയ്യുക, അല്ലെങ്കിൽ 10 സെക്കൻഡിന് ശേഷം ഈ ക്രമീകരണം പുനഃക്രമീകരിക്കപ്പെടും."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ബാറ്ററി (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി സേവർ ലഭ്യമല്ല"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ബാറ്ററി സേവർ"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്‌ക്കുന്നു"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"സിസ്‌റ്റം"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"വീട്"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"പുതിയവ"</string>
+    <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 91c817a..2e8126e 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -470,4 +473,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Хэрэгжүүлэх"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Тохиргоог баталгаажуулах"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Зарим өнгөний тохиргоо энэ төхөөрөмжийг ашиглах боломжгүй болгож болзошгүй. OK товчлуурыг дарж эдгээр өнгөний тохиргоог зөвшөөрөхгүй бол энэ тохиргоо нь 10 секундын дараа шинэчлэгдэх болно."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Тэжээл (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Цэнэглэх үед тэжээл хэмнэгч ажиллахгүй"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Тэжээл хэмнэгч"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Гүйцэтгэл болон дэвсгэрийн датаг багасгадаг"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Нүүр хуудас"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Саяхны"</string>
+    <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 5d3a96f..846e7ee 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"लागू करा"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"सेटिंग्जची पुष्टी करा"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"काही रंग सेटिंग्ज या डिव्हाइसला निरुपयोगी करू शकतात. या रंग सेटिंग्जची पुष्टी करण्‍यासाठी ठीक आहे दाबा अन्यथा या सेटिंग्ज 10 सेकंदांनंतर रीसेट होतील."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"बॅटरी (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज करताना बॅटरी बचतकर्ता उपलब्ध नाही"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"बॅटरी बचतकर्ता"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यप्रदर्शन आणि पार्श्वभूमी डेटा कमी करते"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टीम"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"मुख्यपृष्ठ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"अलीकडील"</string>
+    <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 f0a013c..dd5f767 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Gunakan"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Sahkan tetapan"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Sesetengah tetapan warna boleh menjadikan peranti ini tidak dapat digunakan. Klik OK untuk mengesahkan tetapan warna ini, jika tidak, tetapan ini akan ditetapkan semula selepas 10 saat."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateri (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penjimat Bateri tidak tersedia semasa mengecas"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penjimat Bateri"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangkan prestasi dan data latar belakang"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Skrin Utama"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaharu"</string>
+    <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 75008cb..4bb3a45 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"အသုံးပြုပါ"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ဆက်တင်များကို အတည်ပြုပါ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"အချို့သော အရောင်ဆက်တက်များက ဤကိရိယာကို သုံးမရအောင် လုပ်ပစ်နိုင်ပါသည်။ ဤအရောင် ဆက်တင်များကို အတည်ပြုရန် အိုကေကို နှိပ်ပါ၊ သို့မဟုတ် ဤဆက်တင်များကို ၁၀ စက္ကန့် အကြာတွင် ပြန်ညှိလိုက်ပါမည်။"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ဘက်ထရီ ( <xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"အားသွင်းနေချိန်မှာ Battery Saver ကို သုံးမရပါ"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"လုပ်ဆောင်မှု နှင့် နောက်ခံ ​ဒေတာကို လျော့နည်းစေပါသည်"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"စနစ်"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ပင်မ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"မကြာသေးခင်က"</string>
+    <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-my-rMM/strings_tv.xml b/packages/SystemUI/res/values-my-rMM/strings_tv.xml
new file mode 100644
index 0000000..98d05a9
--- /dev/null
+++ b/packages/SystemUI/res/values-my-rMM/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-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 295a49a..87b2b54 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Bruk"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bekreft innstillingene"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Noen fargeinnstillinger kan gjøre denne enheten ubrukelig. Klikk på OK for å bekrefte disse fargeinnstillingene, ellers blir de tilbakestilt etter ti sekunder."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batteri (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparing er ikke tilgjengelig under lading"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparing"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduserer ytelsen og begrenser bakgrunnsdataene"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startside"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nylige"</string>
+    <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 d0aa510..a56a701 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"लागू गर्नुहोस्"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"सेटिङहरूको पुष्टि गर्नुहोस्"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"केही रङ सेटिङहरूले यस यन्त्रलाई अनुपयोगी बनाउन सक्छन्। यी रङ सेटिङहरू पुष्टि गर्न ठीक छ मा क्लिक गर्नुहोस्, अन्यथा यी सेटिङहरू १० सेकेण्डपछि रिसेट हुनेछन्।"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ब्याट्री (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज गर्ने समयमा ब्याट्री सेभर उपलब्ध छैन"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ब्याट्री सेभर"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यसम्पादन र पृष्ठभूमि डेटा घटाउँछ"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"प्रणाली"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"गृह"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हालैका"</string>
+    <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-ne-rNP/strings_tv.xml b/packages/SystemUI/res/values-ne-rNP/strings_tv.xml
new file mode 100644
index 0000000..09cc01d
--- /dev/null
+++ b/packages/SystemUI/res/values-ne-rNP/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-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 75812ad..a811db3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Toepassen"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Instellingen bevestigen"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bij sommige kleurinstellingen kan het apparaat onbruikbaar worden. Klik op OK om deze kleurinstellingen te bevestigen, anders worden deze instellingen na tien seconden gereset."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Accu (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Accubesparing niet beschikbaar tijdens opladen"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Accubesparing"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vermindert de prestaties en achtergrondgegevens"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systeem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startpagina"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
+    <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-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml
new file mode 100644
index 0000000..59c711d
--- /dev/null
+++ b/packages/SystemUI/res/values-nl/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 sluiten"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Volledig scherm"</string>
+    <string name="pip_play" msgid="674145557658227044">"Afspelen"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Onderbreken"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Annuleren"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Houd HOME ingedrukt om PIP te bedienen"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index fc5a3ea..f3c85eb 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"ਲਾਗੂ ਕਰੋ"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ਸੈਟਿੰਗਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ਕੁਝ ਰੰਗ ਸੈਟਿੰਗਾਂ ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਬੇਕਾਰ ਕਰ ਸਕਦੀਆਂ ਹਨ। ਇਹਨਾਂ ਰੰਗ ਸੈਟਿੰਗਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ ਠੀਕ \'ਤੇ ਕਲਿੱਕ ਕਰੋ, ਨਹੀਂ ਤਾਂ ਇਹ ਸੈਟਿੰਗਾਂ 10 ਸਕਿੰਟ ਬਾਅਦ ਮੁੜ-ਸੈੱਟ ਹੋ ਜਾਣਗੀਆਂ।"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"ਬੈਟਰੀ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"ਬੈਟਰੀ ਸੇਵਰ"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ਕਾਰਗੁਜ਼ਾਰੀ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਡੈਟੇ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ਸਿਸਟਮ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ਹਾਲੀਆ"</string>
+    <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-pa-rIN/strings_tv.xml b/packages/SystemUI/res/values-pa-rIN/strings_tv.xml
new file mode 100644
index 0000000..26cc94a
--- /dev/null
+++ b/packages/SystemUI/res/values-pa-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-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 8ef50c9..4224730 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Zastosuj"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potwierdź ustawienia"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Niektóre ustawienia kolorów mogą utrudniać korzystanie z urządzenia. Kliknij OK, by potwierdzić te ustawienia kolorów. Jeśli tego nie zrobisz, zostaną one zresetowane po 10 sekundach."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Oszczędzanie baterii nie jest dostępne podczas ładowania"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Oszczędzanie baterii"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Zmniejsza wydajność i ogranicza dane w tle"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekran główny"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Ostatnie"</string>
+    <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 8f61478..d81fd8a 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configurações"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algumas configurações de cor podem tornar o dispositivo inutilizável. Clique em \"OK\" para confirmar essas configurações de cor; caso contrário, essas configurações serão redefinidas após 10 segundos."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
+    <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 8a727a1..bfaf659 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar as definições"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algumas definições de cor podem tornar este dispositivo instável. Clique em OK para confirmar estas definições de cor. Caso contrário, estas definições serão repostas após 10 segundos."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Poupança de bateria não disponível durante o carregamento"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Poupança de bateria"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados de segundo plano"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Página inicial"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
+    <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 8f61478..d81fd8a 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configurações"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algumas configurações de cor podem tornar o dispositivo inutilizável. Clique em \"OK\" para confirmar essas configurações de cor; caso contrário, essas configurações serão redefinidas após 10 segundos."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
+    <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 3ab8bf2..484a1b8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -473,4 +476,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicați"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmați setările"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Unele setări pentru culori pot face dispozitivul să nu mai funcționeze. Dați clic pe OK pentru a confirma aceste setări pentru culori. În caz contrar, acestea se vor reseta după 10 secunde."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Baterie (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Economisirea bateriei nu este disponibilă pe durata încărcării"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economisirea bateriei"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce performanța și datele de fundal"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ecran de pornire"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recente"</string>
+    <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 6ffd333..0876366 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Применить"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Подтвердите настройки"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Некоторые цветовые настройки могут затруднить работу с устройством. Чтобы применить выбранные параметры, нажмите \"ОК\". В противном случае они будут сброшены через 10 секунд."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Батарея (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим энергосбережения нельзя включить во время зарядки"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим энергосбережения"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ограничивает производительность и фоновую передачу данных"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Система"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Главный экран"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавние"</string>
+    <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 efbc042..4520aef 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"යොදන්න"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"සැකසීම් තහවුරු කරන්න"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"සමහර වර්ණ සැකසීම් මෙම උපාංගය භාවිත කළ නොහැකි තත්ත්වයට පත් කළ හැකිය. මෙම වර්ණ සැකසීම් තහවුරු කිරීමට හරි ක්ලික් කරන්න, නැතහොත් මෙම සැකසීම් තත්පර 10කට පසුව යළි සකසනු ඇත."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"බැටරිය (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ආරෝපණය අතරතුර බැටරි සුරැකුම ලබා ගත නොහැකිය."</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"බැටරි සුරැකුම"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ක්‍රියාකාරිත්වය සහ පසුබිම් දත්ත අඩු කරන්න"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"පද්ධතිය"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"මුල් පිටුව"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"මෑත"</string>
+    <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 31985b4..7458212 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Použiť"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potvrdenie nastavení"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Niektoré nastavenia farieb môžu toto zariadenie znefunkčniť. Tieto nastavenia farieb potvrdíte kliknutím na tlačidlo OK, ináč sa tieto nastavenia o 10 sekúnd obnovia."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batéria (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Počas nabíjania nie je Šetrič batérie k dispozícii"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Šetrič batérie"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Obmedzí výkonnosť a údaje na pozadí"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systém"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Domovská stránka"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedávne"</string>
+    <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 7c8d443..59037a8 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Uporabi"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potrditev nastavitev"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Zaradi nekaterih barvnih nastavitev lahko postane ta naprava neuporabna. Kliknite »V redu«, če želite potrditi te barvne nastavitve. V nasprotnem primeru se bodo čez 10 sekund ponastavile na prvotno vrednost."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Akumulator (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Varčevanje z energijo akumulatorja med polnjenjem ni na voljo"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Varčevanje z energijo akumulatorja"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omeji zmogljivost delovanja in prenos podatkov v ozadju"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Začetni zaslon"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni"</string>
+    <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 c8add94..7dcad4e 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"Zbato"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Konfirmo cilësimet"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Disa cilësime ngjyrash mund ta bëjnë këtë pajisje të papërdorshme. Kliko OK për të konfirmuar këto cilësime ngjyrash, përndryshe këto cilësime do të rivendosen pas 10 sekondash."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"\"Kursyesi i baterisë\" nuk është i disponueshëm gjatë karikimit"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kursyesi i baterisë"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Pakëson veprimtarinë dhe të dhënat në sfond"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistemi"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Kreu"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Të fundit"</string>
+    <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 bec1fd4..d6a4359 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -473,4 +476,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Примени"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Потврдите подешавања"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Нека подешавања боја могу да учине уређај неупотребљивим. Кликните на Потврди да бисте потврдили ова подешавања боја, пошто ће се у супротном ова подешавања ресетовати након 10 секунди."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Батерија (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Уштеда батерије није доступна током пуњења"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Уштеда батерије"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Смањује перформансе и позадинске податке"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетни"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавни садржај"</string>
+    <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 d4a9cdc..4d8a0e3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Verkställ"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bekräfta inställningarna"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Vissa färginställningar kan göra den här enheten oanvändbar. Klicka på OK om du vill bekräfta färginställningarna, annars återställs inställningarna efter 10 sekunder."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Batteri (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparläget är inte tillgängligt vid laddning"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparläge"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Minskar prestanda och bakgrundsdata"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startsida"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Senaste"</string>
+    <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 2ffbf2b..97b1a3d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Tumia"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Thibitisha mipangilio"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Baadhi ya mipangilio ya rangi inaweza kufanya kifaa hiki kisitumike. Bofya Sawa ili uthibitishe mipangilio hii ya rangi, vinginevyo, mipangilio hii itajiweka upya baada ya sekunde 10."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Betri (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Kiokoa Betri hakipatikani unapochaji betri"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kiokoa Betri"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Hupunguza data ya chini chini na utendaji"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Mfumo"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Mwanzo"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Zilizotumika majuzi"</string>
+    <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-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 168a11b..6efa264 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"பயன்படுத்து"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"அமைப்புகளை உறுதிப்படுத்து"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"சில வண்ண அமைப்புகள் இந்தச் சாதனத்தைப் பயன்படுத்த முடியாதபடி செய்யலாம். இந்த வண்ண அமைப்புகளை உறுதிப்படுத்த, சரி என்பதைக் கிளிக் செய்யவும், இல்லையெனில் இந்த அமைப்புகள் 10 வினாடிகளுக்குப் பின் மீட்டமைக்கப்படும்."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"பேட்டரி (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"சார்ஜ் செய்யும் போது பேட்டரி சேமிப்பானைப் பயன்படுத்த முடியாது"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"பேட்டரி சேமிப்பான்"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"செயல்திறனையும் பின்புலத்தில் தரவு செயலாக்கப்படுவதையும் குறைக்கும்"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"முறைமை"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"முகப்பு"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"சமீபத்தியவை"</string>
+    <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 086dede..2d30739 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +474,17 @@
     <string name="color_apply" msgid="9212602012641034283">"వర్తింపజేయి"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"సెట్టింగ్‌లను నిర్ధారించండి"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"కొన్ని రంగు సెట్టింగ్‌ల వలన ఈ పరికరం ఉపయోగించలేని విధంగా అయిపోవచ్చు. ఈ రంగు సెట్టింగ్‌లను నిర్ధారించడానికి సరే క్లిక్ చేయండి లేదంటే ఈ సెట్టింగ్‌లు 10 సెకన్ల తర్వాత రీసెట్ చేయబడతాయి."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"బ్యాటరీ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ఛార్జ్ అవుతున్న సమయంలో బ్యాటరీ సేవర్ అందుబాటులో ఉండదు"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"బ్యాటరీ సేవర్"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"పనితీరుని మరియు నేపథ్య డేటాను తగ్గిస్తుంది"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"సిస్టమ్"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"హోమ్"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ఇటీవలివి"</string>
+    <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 8c1a7d3..9ac8c16 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"ใช้"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ยืนยันการตั้งค่า"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"การตั้งค่าสีบางอย่างอาจทำให้อุปกรณ์นี้ใช้งานไม่ได้ คลิกตกลงเพื่อยืนยันการตั้งค่าสีเหล่านี้ มิฉะนั้นระบบจะรีเซ็ตการตั้งค่าหลังจาก 10 วินาที"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"แบตเตอรี่ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ไม่สามารถใช้โหมดประหยัดแบตเตอรี่ระหว่างการชาร์จ"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"โหมดประหยัดแบตเตอรี่"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ลดประสิทธิภาพการทำงานและข้อมูลแบ็กกราวด์"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ระบบ"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"หน้าแรก"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ล่าสุด"</string>
+    <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 4bee3ea..1d5a3b4 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Ilapat"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Kumpirmahin ang mga setting"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Maaaring hindi magamit ang device na ito dahil sa ilang setting ng kulay. I-click ang OK upang kumpirmahin ang mga setting ng kulay na ito, kung hindi ay mare-reset ang mga setting na ito pagkatapos ng 10 segundo."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Baterya (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Hindi available ang Pangtipid sa Baterya kapag nagcha-charge"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pangtipid sa Baterya"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Binabawasan ang pagganap at data sa background"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Mga Kamakailang Ginamit"</string>
+    <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 c0ecc78..22108b5 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Uygula"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Ayarları onaylayın"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bazı renkler bu cihazı kullanılmaz yapabilir. Bu renkleri onaylamak için Tamam\'ı tıklayın. Tıklamazsanız bu ayarlar 10 saniye sonra sıfırlanacaktır."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Pil (%%<xliff:g id="ID_1">%1$d</xliff:g>)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Şarj sırasında Pil Tasarrufu özelliği kullanılamaz"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pil Tasarrufu"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı ve arka plan verilerini azaltır"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ana ekran"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Son çağrılar"</string>
+    <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 3109403..615a4c4 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -474,4 +477,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Застосувати"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Підтвердити налаштування"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Деякі налаштування кольорів можуть зробити цей пристрій непридатним для використання. Натисніть OK, щоб підтвердити налаштування, інакше їх буде скинуто через 10 секунд."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Акумулятор (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим економії заряду акумулятора недоступний під час заряджання"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим економії заряду акумулятора"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Знижується продуктивність і обмежується обмін даними у фоновому режимі"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Система"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Головний екран"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Останні"</string>
+    <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-uk/strings_tv.xml b/packages/SystemUI/res/values-uk/strings_tv.xml
new file mode 100644
index 0000000..d36c5bc
--- /dev/null
+++ b/packages/SystemUI/res/values-uk/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-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 52aa580..a789eec 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"لاگو کریں"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ترتیبات کی توثیق کریں"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"رنگوں کی کچھ ترتیبات اس آلے کو ناقابل استعمال بنا سکتی ہیں۔ رنگوں کی ان ترتیبات کی توثیق کرنے کیلئے ٹھیک ہے پر کلک کریں، بصورت دیگر 10 سیکنڈ بعد یہ ترتیبات ری سیٹ ہو جائیں گی۔"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"بیٹری (%%<xliff:g id="ID_1">%1$d</xliff:g>)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"چارجنگ کے دوران بیٹری سیور دستیاب نہیں ہے"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"بیٹری سیور"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"کارکردگی اور پس منظر کا ڈیٹا کم کر دیتا ہے"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"سسٹم"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ہوم"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"حالیہ"</string>
+    <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 a849cfc..4f32c34 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Qo‘llash"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Sozlamalarni tasdiqlang"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Ba’zi rang sozlamalari qurilmadan foydalanishni qiyinlashtirish mumkin. Tanlgan parametrlarni tasdiqlash uchun “OK” tugmasini bosing. Aks holda, ular 10 soniyadan so‘ng qayta tiklanadi."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Quvvat (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Quvvat tejash rejimidan quvvatlash vaqtida foydalanib bo‘lmaydi"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Quvvat tejash rejimi"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Unumdorlikni pasaytiradi va fonda internetdan foydalanishni cheklaydi"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Tizim"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Bosh ekran"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"So‘nggi ishlatilganlar"</string>
+    <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 fa835ba..8108810 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Áp dụng"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Xác nhận cài đặt"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Một số cài đặt màu có thể khiến thiết bị này không sử dụng được. Hãy nhấp vào OK để xác nhận các cài đặt màu này, nếu không những cài đặt này sẽ được đặt lại sau 10 giây."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Pin (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Trình tiết kiệm pin không khả dụng trong khi sạc"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Trình tiết kiệm pin"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Giảm hiệu suất và dữ liệu nền"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Hệ thống"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Màn hình chính"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Gần đây"</string>
+    <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-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml
new file mode 100644
index 0000000..ae5f6da
--- /dev/null
+++ b/packages/SystemUI/res/values-vi/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">"Đóng PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Toàn màn hình"</string>
+    <string name="pip_play" msgid="674145557658227044">"Phát"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Tạm dừng"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Hủy"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Giữ HOME để điều khiển PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 1e2dba3..1829519 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"应用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"确认设置"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"部分颜色设置可能会导致此设备无法使用。请点击“确定”确认这些颜色设置,否则,系统将在 10 秒后重置这些设置。"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"电池 (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用节电助手"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"节电助手"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低性能并限制后台流量"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系统"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主屏幕"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
+    <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 0782354..5d268e8 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"套用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"確認設定"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"部分顏色設定會令此裝置無法使用。請按一下 [確定] 加以確認,否則這些顏色設定將於 10 秒後重設。"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"電池電量 (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用「省電模式」"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"省電模式"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景數據傳輸"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近的活動"</string>
+    <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 29520f6..676e003 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"套用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"確認設定"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"部分顏色設定可能會造成這部裝置無法使用。請按一下 [確定] 來確認您要使用這類顏色設定,否則系統將在 10 秒後重設這些設定。"</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"電池 (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用節約耗電量模式"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"節約耗電量"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景資料傳輸"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"近期活動"</string>
+    <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 3ee46ea..94b9081 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  -->
@@ -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>
@@ -472,4 +475,22 @@
     <string name="color_apply" msgid="9212602012641034283">"Sebenzisa"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Qinisekisa izilungiselelo"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Ezinye izilungiselelo zombala zingenza le divayisi ingasebenziseki. Chofoza ku-KULUNGILE ukuze uqinisekise lezi zilungiselelo zombala, uma kungenjalo lezi zilungiselelo zizosethwa kabusha ngemuva kwamasekhondi angu-10."</string>
+    <string name="battery_panel_title" msgid="3476715163685592453">"Ibhethri (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Isilondolozi sebhethri asitholakali ngesikhathi sokushaja"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Isilondolozi sebhethri"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sehlisa ukusebenza nedatha yasemuva"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Isistimu"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekhaya"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Okwakamuva"</string>
+    <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-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml
new file mode 100644
index 0000000..17764f4
--- /dev/null
+++ b/packages/SystemUI/res/values-zu/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">"Vala i-PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Iskrini esigcwele"</string>
+    <string name="pip_play" msgid="674145557658227044">"Dlala"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Misa isikhashana"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Khansela"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Bamba okuthi Ekhaya ukuze ulawule i-PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values/arrays_car.xml b/packages/SystemUI/res/values/arrays_car.xml
index 230479d..8c760fc 100644
--- a/packages/SystemUI/res/values/arrays_car.xml
+++ b/packages/SystemUI/res/values/arrays_car.xml
@@ -22,7 +22,9 @@
          isn't a longpress action associated with a shortcut item, put in an empty item to make
          sure everything lines up.
     -->
-    <array name="car_shortcut_icons" />
-    <array name="car_shortcut_intent_uris" />
-    <array name="car_shortcut_longpress_intent_uris" />
+    <array name="car_facet_icons" />
+    <array name="car_facet_intent_uris" />
+    <array name="car_facet_longpress_intent_uris" />
+    <array name="car_facet_package_filters"/>
+    <array name="car_facet_category_filters"/>
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 905da13..a80a5de 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -36,7 +36,6 @@
     <color name="system_warning_color">#fff4511e</color><!-- deep orange 600 -->
     <color name="qs_text">#FFFFFFFF</color>
     <color name="qs_tile_divider">#29ffffff</color><!-- 16% white -->
-    <color name="qs_tile_text">#B3FFFFFF</color><!-- 70% white -->
     <color name="qs_subhead">#99FFFFFF</color><!-- 60% white -->
     <color name="qs_detail_empty">#24B0BEC5</color><!-- 14% blue grey 200 -->
     <color name="qs_detail_button">#FFB0BEC5</color><!-- 100% blue grey 200 -->
@@ -48,6 +47,7 @@
     <color name="data_usage_graph_warning">#FFFFFFFF</color>
     <color name="status_bar_clock_color">#FFFFFFFF</color>
     <color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
+    <color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
 
     <!-- Tint color for the content on the notification overflow card. -->
     <color name="keyguard_overflow_content_color">#ff686868</color>
@@ -100,10 +100,9 @@
     <color name="current_user_border_color">@color/system_accent_color</color>
 
     <!-- The "inside" of a notification, reached via longpress -->
-    <color name="notification_guts_bg_color">@*android:color/material_deep_teal_500</color>
-    <color name="notification_guts_title_color">#B2DFDB</color>
-    <color name="notification_guts_text_color">#FFFFFFFF</color>
-    <color name="notification_guts_btn_color">#FFFFFFFF</color>
+    <color name="notification_guts_bg_color">@*android:color/material_grey_50</color>
+    <color name="notification_guts_slider_color">@*android:color/material_deep_teal_500</color>
+    <color name="notification_guts_secondary_slider_color">#858383</color>
 
     <color name="assist_orb_color">#ffffff</color>
 
@@ -147,4 +146,8 @@
 
     <color name="default_remote_input_background">@*android:color/notification_default_color</color>
     <color name="remote_input_hint">#4dffffff</color>
+
+    <color name="qs_tile_tint_unavailable">#40ffffff</color>
+    <color name="qs_tile_tint_inactive">#4dffffff</color>
+    <color name="qs_tile_tint_active">#ffffffff</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 955af82..e98ec82 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -177,6 +177,9 @@
     <!-- The animation duration for scrolling the stack to a particular item. -->
     <integer name="recents_animate_task_stack_scroll_duration">200</integer>
 
+    <!-- The animation duration for scrolling the stack to a particular item. -->
+    <integer name="recents_auto_advance_duration">2000</integer>
+
     <!-- The animation duration for entering and exiting the history. -->
     <integer name="recents_history_transition_duration">250</integer>
 
@@ -279,5 +282,8 @@
     <!-- Whether to show the full screen user switcher. -->
     <bool name="config_enableFullscreenUserSwitcher">false</bool>
 
+    <!-- SystemUIFactory component -->
+    <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
+
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 097c352..47eb05a 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>
@@ -167,6 +165,8 @@
     <dimen name="segmented_button_spacing">0dp</dimen>
     <dimen name="borderless_button_radius">2dp</dimen>
 
+    <dimen name="restricted_padlock_pading">4dp</dimen>
+
     <!-- How far the expanded QS panel peeks from the header in collapsed state. -->
     <dimen name="qs_peek_height">0dp</dimen>
 
@@ -298,7 +298,7 @@
     <dimen name="swipe_helper_falsing_threshold">70dp</dimen>
 
     <dimen name="notifications_top_padding">4dp</dimen>
-    
+
     <!-- Minimum distance the user has to drag down to go to the full shade. -->
     <dimen name="keyguard_drag_down_min_distance">100dp</dimen>
 
@@ -509,7 +509,7 @@
 
     <!-- The maximum width of the navigation bar ripples. -->
     <dimen name="key_button_ripple_max_width">95dp</dimen>
-    
+
     <!-- Inset shadow for FakeShadowDrawable. It is used to avoid gaps between the card
          and the shadow. -->
     <dimen name="fake_shadow_inset">1dp</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 4136c11..814e7ea 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3,16 +3,16 @@
 /**
  * Copyright (c) 2009, The Android Open Source Project
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0 
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 -->
@@ -805,6 +805,12 @@
     <!-- Interruption level: Alarms only.  Optimized for narrow two-line display. [CHAR LIMIT=40] -->
     <string name="interruption_level_alarms_twoline">Alarms\nonly</string>
 
+    <!-- Interruption level: All interruptions. [CHAR LIMIT=40] -->
+    <string name="interruption_level_all">All</string>
+
+    <!-- Interruption level: All interruptions.  Optimized for narrow two-line display. [CHAR LIMIT=40] -->
+    <string name="interruption_level_all_twoline">All\n</string>
+
     <!-- Indication on the keyguard that is shown when the device is charging. [CHAR LIMIT=40]-->
     <string name="keyguard_indication_charging_time">Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
 
@@ -1173,6 +1179,11 @@
     <!-- Description for the toggle for fast-toggling recents via the recents button. DO NOT TRANSLATE -->
     <string name="overview_fast_toggle_via_button_desc">Enable launch timeout while paging</string>
 
+    <!-- Toggles the fast-toggling indicator. DO NOT TRANSLATE -->
+    <string name="overview_fast_toggle_indicator">Enable fast toggle indicator</string>
+    <!-- Description for the fast-toggling indicator. DO NOT TRANSLATE -->
+    <string name="overview_fast_toggle_indicator_desc">Show an indicator for the launch timeout</string>
+
     <!-- Toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
     <string name="overview_initial_state_paging">Initialize to paging</string>
     <!-- Description for the toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
@@ -1281,4 +1292,45 @@
     <!-- Summary of switch for battery saver [CHAR LIMIT=NONE] -->
     <string name="battery_detail_switch_summary">Reduces performance and background data</string>
 
+    <!-- User visible title for the system-wide keyboard shortcuts list. -->
+    <string name="keyboard_shortcut_group_system">System</string>
+    <!-- User visible title for the keyboard shortcut that takes the user to the home screen. -->
+    <string name="keyboard_shortcut_group_system_home">Home</string>
+    <!-- User visible title for the the keyboard shortcut that takes the user to the recents screen. -->
+    <string name="keyboard_shortcut_group_system_recents">Recents</string>
+    <!-- User visible title for the the keyboard shortcut that triggers the back action. -->
+    <string name="keyboard_shortcut_group_system_back">Back</string>
+
+    <!-- SysUI Tuner: Option to show full do not disturb panel in volume [CHAR LIMIT=60] -->
+    <string name="tuner_full_zen_title">Show do not disturb in volume</string>
+    <!-- SysUI Tuner: Summary of option to show full do not disturb panel in volume [CHAR LIMIT=NONE] -->
+    <string name="tuner_full_zen_summary">Allow full control of do not disturb in the volume dialog.</string>
+
+    <!-- SysUI Tuner: Label for screen about volume and do not disturb settings [CHAR LIMIT=60] -->
+    <string name="volume_and_do_not_disturb">Volume and Do not disturb</string>
+
+    <!-- SysUI Tuner: Switch to control volume down behavior [CHAR LIMIT=60] -->
+    <string name="volume_down_silent">Enter do not disturb on volume down</string>
+
+    <!-- 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/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml
new file mode 100644
index 0000000..d432a62
--- /dev/null
+++ b/packages/SystemUI/res/values/strings_tv.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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Button to close PIP on PIP UI -->
+    <string name="pip_exit">Close PIP</string>
+    <!-- Button to move PIP screen to the fullscreen on PIP UI -->
+    <string name="pip_fullscreen">Full screen</string>
+    <!-- Button to play the current media on PIP UI -->
+    <string name="pip_play">Play</string>
+    <!-- Button to pause the current media on PIP UI -->
+    <string name="pip_pause">Pause</string>
+    <!-- Button to close PIP overlay menu on PIP UI -->
+    <string name="pip_cancel">Cancel</string>
+    <!-- Overlay text on PIP -->
+    <string name="pip_hold_home">Hold HOME to control PIP</string>
+</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 527b638..4329f78 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -319,10 +319,30 @@
 
     <style name="TextAppearance.NotificationGuts">
         <item name="android:textSize">14sp</item>
-        <item name="android:textColor">@color/notification_guts_btn_color</item>
+        <item name="android:fontFamily">sans-serif-medium</item>
+        <item name="android:textColor">@android:color/black</item>
+    </style>
+
+    <style name="TextAppearance.NotificationGuts.Header">
+        <item name="android:alpha">.38</item>
+        <item name="android:textSize">12sp</item>
+    </style>
+
+    <style name="TextAppearance.NotificationGuts.Secondary">
+        <item name="android:alpha">.54</item>
+    </style>
+
+    <style name="TextAppearance.NotificationGuts.Primary">
+        <item name="android:alpha">.87</item>
+        <item name="android:textSize">16sp</item>
+    </style>
+
+    <style name="TextAppearance.NotificationGuts.Button">
+        <item name="android:textSize">14sp</item>
         <item name="android:textAllCaps">true</item>
         <item name="android:fontFamily">sans-serif-medium</item>
         <item name="android:gravity">center</item>
+        <item name="android:textColor">@*android:color/material_deep_teal_500</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/values/styles_tv.xml b/packages/SystemUI/res/values/styles_tv.xml
new file mode 100644
index 0000000..3f0caab
--- /dev/null
+++ b/packages/SystemUI/res/values/styles_tv.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.
+ */
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="PipTheme" parent="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:backgroundDimEnabled">false</item>
+     </style>
+</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 90cd394..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>
 
 
@@ -84,6 +122,12 @@
             android:title="@string/overview_fast_toggle_via_button"
             android:summary="@string/overview_fast_toggle_via_button_desc" />
 
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="overview_fast_toggle_indicator"
+            android:title="@string/overview_fast_toggle_indicator"
+            android:summary="@string/overview_fast_toggle_indicator_desc"
+            android:dependency="overview_fast_toggle_via_button" />
+
     </PreferenceScreen>
 
     <SwitchPreference
@@ -107,6 +151,27 @@
         android:title="@string/color_transform"
         android:fragment="com.android.systemui.tuner.ColorMatrixFragment" />
 
+    <PreferenceScreen
+        android:key="volume_and_do_not_disturb"
+        android:title="@string/volume_and_do_not_disturb">
+
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="sysui_show_full_zen"
+            android:title="@string/tuner_full_zen_title"
+            android:summary="@string/tuner_full_zen_summary" />
+
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="sysui_volume_down_silent"
+            android:title="@string/volume_down_silent"
+            sysui:defValue="true" />
+
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="sysui_volume_up_silent"
+            android:title="@string/volume_up_silent"
+            sysui:defValue="true" />
+
+    </PreferenceScreen>
+
     <!-- Warning, this goes last. -->
     <Preference
         android:summary="@string/tuner_persistent_warning"
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 870e0af..d28da41 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -86,6 +86,7 @@
     final private int[] mTmpPos = new int[2];
     private int mFalsingThreshold;
     private boolean mTouchAboveFalsingThreshold;
+    private boolean mDisableHwLayers;
 
     public SwipeHelper(int swipeDirection, Callback callback, Context context) {
         mCallback = callback;
@@ -115,6 +116,10 @@
         mPagingTouchSlop = pagingTouchSlop;
     }
 
+    public void setDisableHardwareLayers(boolean disableHwLayers) {
+        mDisableHwLayers = disableHwLayers;
+    }
+
     private float getPos(MotionEvent ev) {
         return mSwipeDirection == X ? ev.getX() : ev.getY();
     }
@@ -130,7 +135,7 @@
 
     private ObjectAnimator createTranslationAnimation(View v, float newPos) {
         ObjectAnimator anim = ObjectAnimator.ofFloat(v,
-                mSwipeDirection == X ? "translationX" : "translationY", newPos);
+                mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
         return anim;
     }
 
@@ -147,7 +152,7 @@
         }
     }
 
-    private float getSize(View v) {
+    protected float getSize(View v) {
         return mSwipeDirection == X ? v.getMeasuredWidth() :
                 v.getMeasuredHeight();
     }
@@ -178,10 +183,12 @@
         if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) {
             if (FADE_OUT_DURING_SWIPE && dismissable) {
                 float alpha = swipeProgress;
-                if (alpha != 0f && alpha != 1f) {
-                    animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-                } else {
-                    animView.setLayerType(View.LAYER_TYPE_NONE, null);
+                if (!mDisableHwLayers) {
+                    if (alpha != 0f && alpha != 1f) {
+                        animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                    } else {
+                        animView.setLayerType(View.LAYER_TYPE_NONE, null);
+                    }
                 }
                 animView.setAlpha(getSwipeProgressForOffset(animView));
             }
@@ -345,7 +352,9 @@
             duration = fixedDuration;
         }
 
-        animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        if (!mDisableHwLayers) {
+            animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        }
         ObjectAnimator anim = createTranslationAnimation(animView, newPos);
         if (useAccelerateInterpolator) {
             anim.setInterpolator(mFastOutLinearInInterpolator);
@@ -362,7 +371,9 @@
                 if (endAction != null) {
                     endAction.run();
                 }
-                animView.setLayerType(View.LAYER_TYPE_NONE, null);
+                if (!mDisableHwLayers) {
+                    animView.setLayerType(View.LAYER_TYPE_NONE, null);
+                }
             }
         });
         anim.addUpdateListener(new AnimatorUpdateListener() {
@@ -390,9 +401,17 @@
                 mCallback.onChildSnappedBack(animView);
             }
         });
+        updateSnapBackAnimation(anim);
         anim.start();
     }
 
+    /**
+     * Called to update the snap back animation.
+     */
+    protected void updateSnapBackAnimation(Animator anim) {
+        // Do nothing
+    }
+
     public boolean onTouchEvent(MotionEvent ev) {
         if (mLongPressSent) {
             return true;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 19e299254..472648a 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -54,6 +54,7 @@
             com.android.systemui.power.PowerUI.class,
             com.android.systemui.media.RingtonePlayer.class,
             com.android.systemui.keyboard.KeyboardUI.class,
+            com.android.systemui.tv.pip.PipUI.class
     };
 
     /**
@@ -80,6 +81,8 @@
         // the theme set there.
         setTheme(R.style.systemui_theme);
 
+        SystemUIFactory.createFromConfig(this);
+
         if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
             IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
             filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
new file mode 100644
index 0000000..681b39e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.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 com.android.systemui;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.ViewGroup;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarWindowManager;
+
+/**
+ * Class factory to provide customizable SystemUI components.
+ */
+public class SystemUIFactory {
+    private static final String TAG = "SystemUIFactory";
+
+    static SystemUIFactory mFactory;
+
+    public static SystemUIFactory getInstance() {
+        return mFactory;
+    }
+
+    public static void createFromConfig(Context context) {
+        final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
+        if (clsName == null || clsName.length() == 0) {
+            throw new RuntimeException("No SystemUIFactory component configured");
+        }
+
+        try {
+            Class<?> cls = null;
+            cls = context.getClassLoader().loadClass(clsName);
+            mFactory = (SystemUIFactory) cls.newInstance();
+        } catch (Throwable t) {
+            Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t);
+            throw new RuntimeException(t);
+        }
+    }
+
+    public SystemUIFactory() {}
+
+    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
+            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
+        return new StatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
+    }
+
+    public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback,
+            LockPatternUtils lockPatternUtils, StatusBarWindowManager windowManager,
+            ViewGroup container) {
+        return new KeyguardBouncer(context, callback, lockPatternUtils, windowManager, container);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7556c6b..9a00b4b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -69,6 +69,7 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.statusbar.phone.FingerprintUnlockController;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
@@ -591,8 +592,9 @@
         updateInputRestrictedLocked();
         mTrustManager.reportKeyguardShowingChanged();
 
-        mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
-                mViewMediatorCallback, mLockPatternUtils);
+        mStatusBarKeyguardViewManager =
+                SystemUIFactory.getInstance().createStatusBarKeyguardViewManager(mContext,
+                        mViewMediatorCallback, mLockPatternUtils);
         final ContentResolver cr = mContext.getContentResolver();
 
         mDeviceInteractive = mPM.isInteractive();
@@ -744,8 +746,7 @@
 
         long timeout;
 
-        UserInfo user = UserManager.get(mContext).getUserInfo(userId);
-        if ((!user.isManagedProfile() && LockPatternUtils.isSeparateWorkChallengeEnabled())
+        if ((mLockPatternUtils.isSeparateProfileChallengeEnabled(userId))
                 || policyTimeout <= 0) {
             timeout = lockAfterTimeout;
         } else {
@@ -785,9 +786,9 @@
     private void doKeyguardLaterLockedForChildProfiles() {
         UserManager um = UserManager.get(mContext);
         List<UserInfo> profiles = um.getEnabledProfiles(UserHandle.myUserId());
-        if (LockPatternUtils.isSeparateWorkChallengeEnabled() && profiles.size() > 1) {
+        if (profiles.size() > 1) {
             for (UserInfo info : profiles) {
-                if (info.id != UserHandle.myUserId() && info.isManagedProfile()) {
+                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(info.id)) {
                     long userTimeout = getLockTimeout(info.id);
                     long userWhen = SystemClock.elapsedRealtime() + userTimeout;
                     Intent lockIntent = new Intent(DELAYED_LOCK_PROFILE_ACTION);
@@ -1737,10 +1738,15 @@
     public void onActivityDrawn() {
         mHandler.sendEmptyMessage(ON_ACTIVITY_DRAWN);
     }
+
     public ViewMediatorCallback getViewMediatorCallback() {
         return mViewMediatorCallback;
     }
 
+    public LockPatternUtils getLockPatternUtils() {
+        return mLockPatternUtils;
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print("  mSystemReady: "); pw.println(mSystemReady);
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/QSIconView.java b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
index 01eb5f9..7651ae8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
@@ -81,7 +81,11 @@
                 }
             }
         }
-
+        if (state.disabledByPolicy) {
+            iv.setColorFilter(getContext().getColor(R.color.qs_tile_disabled_color));
+        } else {
+            iv.clearColorFilter();
+        }
     }
 
     protected int getIconMeasureMode() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 91f88b9..b5f146b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -329,16 +329,19 @@
                     drawTile(r, state);
                 }
             }
+
             @Override
             public void onShowDetail(boolean show) {
                 QSPanel.this.showDetail(show, r);
             }
+
             @Override
             public void onToggleStateChanged(boolean state) {
                 if (mDetailRecord == r) {
                     fireToggleStateChanged(state);
                 }
             }
+
             @Override
             public void onScanStateChanged(boolean state) {
                 r.scanState = state;
@@ -352,7 +355,7 @@
                 announceForAccessibility(announcement);
             }
         };
-        r.tile.setCallback(callback);
+        r.tile.addCallback(callback);
         final View.OnClickListener click = new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -415,6 +418,9 @@
     }
 
     protected void handleShowDetail(Record r, boolean show) {
+        if (show && !mExpanded) {
+            mHost.animateExpandQS();
+        }
         if (r instanceof TileRecord) {
             handleShowDetailTile((TileRecord) r, show);
         } else {
@@ -551,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;
     }
@@ -601,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 8ce6da2..72629a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -23,10 +23,13 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.UserHandle;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
+
+import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.qs.QSTile.State;
 import com.android.systemui.qs.external.TileServices;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -43,9 +46,12 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Objects;
 
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
 /**
  * Base quick-settings tile, extend this to create a new tile.
  *
@@ -62,7 +68,7 @@
     protected final H mHandler;
     protected final Handler mUiHandler = new Handler(Looper.getMainLooper());
 
-    private Callback mCallback;
+    private final ArrayList<Callback> mCallbacks = new ArrayList<>();
     protected TState mState = newTileState();
     private TState mTmpState = newTileState();
     private boolean mAnnounceNextStateChange;
@@ -119,8 +125,12 @@
 
     // safe to call from any thread
 
-    public void setCallback(Callback callback) {
-        mHandler.obtainMessage(H.SET_CALLBACK, callback).sendToTarget();
+    public void addCallback(Callback callback) {
+        mHandler.obtainMessage(H.ADD_CALLBACK, callback).sendToTarget();
+    }
+
+    public void removeCallbacks() {
+        mHandler.sendEmptyMessage(H.REMOVE_CALLBACKS);
     }
 
     public void click() {
@@ -177,11 +187,15 @@
 
     // call only on tile worker looper
 
-    private void handleSetCallback(Callback callback) {
-        mCallback = callback;
+    private void handleAddCallback(Callback callback) {
+        mCallbacks.add(callback);
         handleRefreshState(null);
     }
 
+    private void handleRemoveCallbacks() {
+        mCallbacks.clear();
+    }
+
     protected void handleSecondaryClick() {
         // Default to normal click.
         handleClick();
@@ -206,12 +220,14 @@
 
     private void handleStateChanged() {
         boolean delayAnnouncement = shouldAnnouncementBeDelayed();
-        if (mCallback != null) {
-            mCallback.onStateChanged(mState);
+        if (mCallbacks.size() != 0) {
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                mCallbacks.get(i).onStateChanged(mState);
+            }
             if (mAnnounceNextStateChange && !delayAnnouncement) {
                 String announcement = composeChangeAnnouncement();
                 if (announcement != null) {
-                    mCallback.onAnnouncementRequested(announcement);
+                    mCallbacks.get(0).onAnnouncementRequested(announcement);
                 }
             }
         }
@@ -227,20 +243,20 @@
     }
 
     private void handleShowDetail(boolean show) {
-        if (mCallback != null) {
-            mCallback.onShowDetail(show);
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            mCallbacks.get(i).onShowDetail(show);
         }
     }
 
     private void handleToggleStateChanged(boolean state) {
-        if (mCallback != null) {
-            mCallback.onToggleStateChanged(state);
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            mCallbacks.get(i).onToggleStateChanged(state);
         }
     }
 
     private void handleScanStateChanged(boolean state) {
-        if (mCallback != null) {
-            mCallback.onScanStateChanged(state);
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            mCallbacks.get(i).onScanStateChanged(state);
         }
     }
 
@@ -250,11 +266,23 @@
 
     protected void handleDestroy() {
         setListening(false);
-        mCallback = null;
+        mCallbacks.clear();
+    }
+
+    protected void checkIfRestrictionEnforced(State state, String userRestriction) {
+        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                userRestriction, UserHandle.myUserId());
+        if (admin != null) {
+            state.disabledByPolicy = true;
+            state.enforcedAdmin = admin;
+        } else {
+            state.disabledByPolicy = false;
+            state.enforcedAdmin = null;
+        }
     }
 
     protected final class H extends Handler {
-        private static final int SET_CALLBACK = 1;
+        private static final int ADD_CALLBACK = 1;
         private static final int CLICK = 2;
         private static final int SECONDARY_CLICK = 3;
         private static final int LONG_CLICK = 4;
@@ -265,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);
@@ -274,13 +303,22 @@
         public void handleMessage(Message msg) {
             String name = null;
             try {
-                if (msg.what == SET_CALLBACK) {
-                    name = "handleSetCallback";
-                    handleSetCallback((QSTile.Callback)msg.obj);
+                if (msg.what == ADD_CALLBACK) {
+                    name = "handleAddCallback";
+                    handleAddCallback((QSTile.Callback) msg.obj);
+                } else if (msg.what == REMOVE_CALLBACKS) {
+                    name = "handleRemoveCallbacks";
+                    handleRemoveCallbacks();
                 } else if (msg.what == CLICK) {
                     name = "handleClick";
-                    mAnnounceNextStateChange = true;
-                    handleClick();
+                    if (mState.disabledByPolicy) {
+                        Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent(
+                                mContext, mState.enforcedAdmin);
+                        mHost.startActivityDismissingKeyguard(intent);
+                    } else {
+                        mAnnounceNextStateChange = true;
+                        handleClick();
+                    }
                 } else if (msg.what == SECONDARY_CLICK) {
                     name = "handleSecondaryClick";
                     handleSecondaryClick();
@@ -333,6 +371,7 @@
         void startRunnableDismissingKeyguard(Runnable runnable);
         void warn(String message, Throwable t);
         void collapsePanels();
+        void animateExpandQS();
         void openPanels();
         Looper getLooper();
         Context getContext();
@@ -433,6 +472,8 @@
         public CharSequence contentDescription;
         public CharSequence dualLabelContentDescription;
         public boolean autoMirrorDrawable = true;
+        public boolean disabledByPolicy;
+        public EnforcedAdmin enforcedAdmin;
 
         public boolean copyTo(State other) {
             if (other == null) throw new IllegalArgumentException();
@@ -442,12 +483,22 @@
                     || !Objects.equals(other.contentDescription, contentDescription)
                     || !Objects.equals(other.autoMirrorDrawable, autoMirrorDrawable)
                     || !Objects.equals(other.dualLabelContentDescription,
-                    dualLabelContentDescription);
+                    dualLabelContentDescription)
+                    || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
+                    || !Objects.equals(other.enforcedAdmin, enforcedAdmin);
             other.icon = icon;
             other.label = label;
             other.contentDescription = contentDescription;
             other.dualLabelContentDescription = dualLabelContentDescription;
             other.autoMirrorDrawable = autoMirrorDrawable;
+            other.disabledByPolicy = disabledByPolicy;
+            if (enforcedAdmin == null) {
+                other.enforcedAdmin = null;
+            } else if (other.enforcedAdmin == null) {
+                other.enforcedAdmin = new EnforcedAdmin(enforcedAdmin);
+            } else {
+                enforcedAdmin.copyTo(other.enforcedAdmin);
+            }
             return changed;
         }
 
@@ -463,6 +514,8 @@
             sb.append(",contentDescription=").append(contentDescription);
             sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
             sb.append(",autoMirrorDrawable=").append(autoMirrorDrawable);
+            sb.append(",disabledByPolicy=").append(disabledByPolicy);
+            sb.append(",enforcedAdmin=").append(enforcedAdmin);
             return sb.append(']');
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 41ac4d9..664ca39 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -19,32 +19,33 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Typeface;
 import android.util.MathUtils;
-import android.util.TypedValue;
 import android.view.Gravity;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.ImageView;
 import android.widget.TextView;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 
 /** View that represents a standard quick settings tile. **/
 public class QSTileView extends QSTileBaseView {
-    private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed",
-            Typeface.NORMAL);
-
     protected final Context mContext;
+    private QSIconView mIconView;
     private final int mTileSpacingPx;
     private int mTilePaddingTopPx;
 
     private TextView mLabel;
+    private ImageView mPadLock;
 
     public QSTileView(Context context, QSIconView icon) {
         super(context, icon);
 
         mContext = context;
+        mIconView = icon;
         final Resources res = context.getResources();
         mTileSpacingPx = res.getDimensionPixelSize(R.dimen.qs_tile_spacing);
+
         setClipChildren(false);
 
         setClickable(true);
@@ -76,16 +77,10 @@
 
     private void createLabel() {
         final Resources res = mContext.getResources();
-        mLabel = new TextView(mContext);
-        mLabel.setTextColor(mContext.getColor(R.color.qs_tile_text));
-        mLabel.setGravity(Gravity.CENTER_HORIZONTAL);
-        mLabel.setMinLines(2);
-        mLabel.setPadding(0, 0, 0, 0);
-        mLabel.setTypeface(CONDENSED);
-        mLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                res.getDimensionPixelSize(R.dimen.qs_tile_text_size));
-        mLabel.setClickable(false);
-        addView(mLabel);
+        View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null);
+        mLabel = (TextView) view.findViewById(R.id.tile_label);
+        mPadLock = (ImageView) view.findViewById(R.id.restricted_padlock);
+        addView(view);
     }
 
     public void init(OnClickListener clickPrimary, OnLongClickListener longClick) {
@@ -96,5 +91,7 @@
     protected void handleStateChanged(QSTile.State state) {
         super.handleStateChanged(state);
         mLabel.setText(state.label);
+        mLabel.setEnabled(!state.disabledByPolicy);
+        mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 5fa38c6..b391c1e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -60,14 +60,8 @@
     }
 
     @Override
-    protected void handleShowDetail(QSPanel.Record r, boolean show) {
-        if (show) {
-            mHeader.performClick();
-            mFullPanel.showDetail(show, r);
-        } else {
-            // Not sure how we would end up here...
-            super.handleShowDetail(r, show);
-        }
+    protected void showDetail(boolean show, Record r) {
+        // Do nothing, will be handled by the QSPanel.
     }
 
     @Override
@@ -151,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/BlankCustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
index 95ff611..ac4f05f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
@@ -19,8 +19,9 @@
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
-
+import android.graphics.drawable.Drawable;
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 
 public class BlankCustomTile extends QSTile<QSTile.State> {
@@ -72,7 +73,9 @@
         try {
             PackageManager pm = mContext.getPackageManager();
             ServiceInfo info = pm.getServiceInfo(mComponent, 0);
-            state.icon = new DrawableIcon(info.loadIcon(pm));
+            Drawable drawable = info.loadIcon(pm);
+            drawable.setTint(mContext.getColor(R.color.qs_tile_tint_active));
+            state.icon = new DrawableIcon(drawable);
             state.label = info.loadLabel(pm).toString();
             state.contentDescription = state.label;
         } catch (Exception e) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java
index 7448493..eab4dca 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java
@@ -69,6 +69,11 @@
     }
 
     @Override
+    protected void showDetail(boolean show, Record r) {
+        // No detail here.
+    }
+
+    @Override
     protected void onDetachedFromWindow() {
         // Don't allow the super to unregister the tunable.
     }
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/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index eefff30..d398b64 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -25,11 +25,14 @@
 import android.service.quicksettings.IQSTileService;
 import android.service.quicksettings.Tile;
 import android.service.quicksettings.TileService;
+import android.text.SpannableStringBuilder;
+import android.text.style.ForegroundColorSpan;
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.phone.QSTileHost;
 
@@ -88,6 +91,7 @@
         mTile.setIcon(tile.getIcon());
         mTile.setLabel(tile.getLabel());
         mTile.setContentDescription(tile.getContentDescription());
+        mTile.setState(tile.getState());
     }
 
     public void onDialogShown() {
@@ -147,6 +151,9 @@
 
     @Override
     protected void handleClick() {
+        if (mTile.getState() == Tile.STATE_UNAVAILABLE) {
+            return;
+        }
         try {
             if (DEBUG) Log.d(TAG, "Adding token");
             mWindowManager.addWindowToken(mToken, WindowManager.LayoutParams.TYPE_QS_DIALOG);
@@ -172,9 +179,15 @@
     @Override
     protected void handleUpdateState(State state, Object arg) {
         Drawable drawable = mTile.getIcon().loadDrawable(mContext);
-        drawable.setTint(mContext.getColor(android.R.color.white));
+        int color = mContext.getColor(getColor(mTile.getState()));
+        drawable.setTint(color);
         state.icon = new DrawableIcon(drawable);
         state.label = mTile.getLabel();
+        if (mTile.getState() == Tile.STATE_UNAVAILABLE) {
+            state.label = new SpannableStringBuilder().append(state.label,
+                    new ForegroundColorSpan(color),
+                    SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
+        }
         if (mTile.getContentDescription() != null) {
             state.contentDescription = mTile.getContentDescription();
         } else {
@@ -187,6 +200,30 @@
         return MetricsLogger.QS_CUSTOM;
     }
 
+    public void startUnlockAndRun() {
+        mHost.startRunnableDismissingKeyguard(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    mService.onUnlockComplete();
+                } catch (RemoteException e) {
+                }
+            }
+        });
+    }
+
+    private static int getColor(int state) {
+        switch (state) {
+            case Tile.STATE_UNAVAILABLE:
+                return R.color.qs_tile_tint_unavailable;
+            case Tile.STATE_INACTIVE:
+                return R.color.qs_tile_tint_inactive;
+            case Tile.STATE_ACTIVE:
+                return R.color.qs_tile_tint_active;
+        }
+        return 0;
+    }
+
     public static ComponentName getComponentFromSpec(String spec) {
         final String action = spec.substring(PREFIX.length(), spec.length() - 1);
         if (action.isEmpty()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
index d41cdde..3830ac5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java
@@ -104,4 +104,14 @@
             return false;
         }
     }
+
+    public boolean onUnlockComplete() {
+        try {
+            mService.onUnlockComplete();
+            return true;
+        } catch (Exception e) {
+            Log.d(TAG, "Caught exception from TileService", e);
+            return false;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 8c5e87e..4977d80 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -55,6 +55,7 @@
     private static final int MSG_ON_ADDED = 0;
     private static final int MSG_ON_REMOVED = 1;
     private static final int MSG_ON_CLICK = 2;
+    private static final int MSG_ON_UNLOCK_COMPLETE = 3;
 
     // Bind retry control.
     private static final int MAX_BIND_RETRIES = 5;
@@ -174,6 +175,15 @@
                 onClick(mClickBinder);
             }
         }
+        if (queue.contains(MSG_ON_UNLOCK_COMPLETE)) {
+            if (DEBUG) Log.d(TAG, "Handling pending onUnlockComplete");
+            if (!mListening) {
+                Log.w(TAG, "Managed to get unlock on non-listening state...");
+                // Skipping unlock since lost click privileges.
+            } else {
+                onUnlockComplete();
+            }
+        }
         if (queue.contains(MSG_ON_REMOVED)) {
             if (DEBUG) Log.d(TAG, "Handling pending onRemoved");
             if (mListening) {
@@ -348,6 +358,15 @@
     }
 
     @Override
+    public void onUnlockComplete() {
+        if (DEBUG) Log.d(TAG, "onUnlockComplete");
+        if (mWrapper == null || !mWrapper.onUnlockComplete()) {
+            queueMessage(MSG_ON_UNLOCK_COMPLETE);
+            handleDeath();
+        }
+    }
+
+    @Override
     public IBinder asBinder() {
         return mWrapper != null ? mWrapper.asBinder() : null;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index a831c87..44d8776 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -36,6 +36,7 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.statusbar.phone.QSTileHost;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -199,6 +200,16 @@
     }
 
     @Override
+    public void onStartActivity(Tile tile) {
+        ComponentName componentName = tile.getComponentName();
+        verifyCaller(componentName.getPackageName());
+        CustomTile customTile = getTileForComponent(componentName);
+        if (customTile != null) {
+            mHost.collapsePanels();
+        }
+    }
+
+    @Override
     public void updateStatusIcon(Tile tile, Icon icon, String contentDescription) {
         final ComponentName componentName = tile.getComponentName();
         String packageName = componentName.getPackageName();
@@ -228,6 +239,28 @@
         }
     }
 
+    @Override
+    public void startUnlockAndRun(Tile tile) {
+        ComponentName componentName = tile.getComponentName();
+        verifyCaller(componentName.getPackageName());
+        CustomTile customTile = getTileForComponent(componentName);
+        if (customTile != null) {
+            customTile.startUnlockAndRun();
+        }
+    }
+
+    @Override
+    public boolean isLocked() {
+        KeyguardMonitor keyguardMonitor = mHost.getKeyguardMonitor();
+        return keyguardMonitor.isShowing();
+    }
+
+    @Override
+    public boolean isSecure() {
+        KeyguardMonitor keyguardMonitor = mHost.getKeyguardMonitor();
+        return keyguardMonitor.isSecure() && keyguardMonitor.isShowing();
+    }
+
     private CustomTile getTileForComponent(ComponentName component) {
         synchronized (mServices) {
             return mTiles.get(component);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index c1dcfea..1f8fae0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -24,7 +24,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import com.android.internal.logging.MetricsLogger;
-import com.android.settingslib.net.MobileDataController;
+import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSIconView;
 import com.android.systemui.qs.QSTile;
@@ -39,7 +39,7 @@
             "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
 
     private final NetworkController mController;
-    private final MobileDataController mDataController;
+    private final DataUsageController mDataController;
     private final CellularDetailAdapter mDetailAdapter;
 
     private final CellSignalCallback mSignalCallback = new CellSignalCallback();
@@ -255,7 +255,7 @@
             final DataUsageDetailView v = (DataUsageDetailView) (convertView != null
                     ? convertView
                     : LayoutInflater.from(mContext).inflate(R.layout.data_usage, parent, false));
-            final MobileDataController.DataUsageInfo info = mDataController.getDataUsageInfo();
+            final DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo();
             if (info == null) return v;
             v.bind(info);
             return v;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
index d814b1c2..2be43c0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
@@ -23,7 +23,7 @@
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-import com.android.settingslib.net.MobileDataController;
+import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.DataUsageGraph;
@@ -59,7 +59,7 @@
                 R.dimen.qs_data_usage_text_size);
     }
 
-    public void bind(MobileDataController.DataUsageInfo info) {
+    public void bind(DataUsageController.DataUsageInfo info) {
         final Resources res = mContext.getResources();
         final int titleId;
         final long bytes;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 4d9b266..39eda6b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -22,6 +22,7 @@
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.view.LayoutInflater;
@@ -99,14 +100,6 @@
 
     @Override
     public void handleClick() {
-        if (mController.isVolumeRestricted()) {
-            // Collapse the panels, so the user can see the toast.
-            mHost.collapsePanels();
-            SysUIToast.makeText(mContext, mContext.getString(
-                    com.android.internal.R.string.error_message_change_not_allowed),
-                    Toast.LENGTH_LONG).show();
-            return;
-        }
         MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
         if (mState.value) {
             mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
@@ -123,6 +116,8 @@
         final boolean newValue = zen != Global.ZEN_MODE_OFF;
         final boolean valueChanged = state.value != newValue;
         state.value = newValue;
+        state.disabledByPolicy = mController.isVolumeRestricted();
+        checkIfRestrictionEnforced(state, UserManager.DISALLOW_ADJUST_VOLUME);
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
                 state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
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/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index 21c5c96..167c611 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -43,6 +43,7 @@
     private TextView mName;
     private Typeface mRegularTypeface;
     private Typeface mActivatedTypeface;
+    private View mRestrictedPadlock;
 
     public UserDetailItemView(Context context) {
         this(context, null);
@@ -59,6 +60,7 @@
     public UserDetailItemView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.UserDetailItemView, defStyleAttr, defStyleRes);
         final int N = a.getIndexCount();
@@ -95,6 +97,12 @@
         mAvatar.setDrawable(picture);
     }
 
+    public void setDisabledByAdmin(boolean disabled) {
+        mRestrictedPadlock.setVisibility(disabled ? View.VISIBLE : View.GONE);
+        mName.setEnabled(!disabled);
+        mAvatar.setDisabled(disabled);
+    }
+
     @Override
     protected void onFinishInflate() {
         mAvatar = (UserAvatarView) findViewById(R.id.user_picture);
@@ -106,6 +114,7 @@
             mActivatedTypeface = mName.getTypeface();
         }
         updateTypeface();
+        mRestrictedPadlock = findViewById(R.id.restricted_padlock);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index d4f54b6..b44ef0b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -16,17 +16,18 @@
 
 package com.android.systemui.qs.tiles;
 
-import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.R;
-import com.android.systemui.qs.PseudoGridView;
-import com.android.systemui.statusbar.policy.UserSwitcherController;
-
 import android.content.Context;
+import android.content.Intent;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.systemui.R;
+import com.android.systemui.qs.PseudoGridView;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
 /**
  * Quick settings detail view for user switching.
  */
@@ -55,11 +56,13 @@
     public static class Adapter extends UserSwitcherController.BaseUserAdapter
             implements OnClickListener {
 
-        private Context mContext;
+        private final Context mContext;
+        private final UserSwitcherController mController;
 
         public Adapter(Context context, UserSwitcherController controller) {
             super(controller);
             mContext = context;
+            mController = controller;
         }
 
         @Override
@@ -77,6 +80,7 @@
                 v.bind(name, item.picture);
             }
             v.setActivated(item.isCurrent);
+            v.setDisabledByAdmin(item.isDisabledByAdmin);
             v.setTag(item);
             return v;
         }
@@ -85,8 +89,14 @@
         public void onClick(View view) {
             UserSwitcherController.UserRecord tag =
                     (UserSwitcherController.UserRecord) view.getTag();
-            MetricsLogger.action(mContext, MetricsLogger.QS_SWITCH_USER);
-            switchTo(tag);
+            if (tag.isDisabledByAdmin) {
+                final Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent(
+                        mContext, tag.enforcedAdmin);
+                mController.startActivity(intent);
+            } else {
+                MetricsLogger.action(mContext, MetricsLogger.QS_SWITCH_USER);
+                switchTo(tag);
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 255f29f..34ed37b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -47,6 +47,7 @@
         super(host);
         mUserManager = UserManager.get(mContext);
         mProfiles = new LinkedList<UserInfo>();
+        reloadManagedProfiles(UserHandle.USER_CURRENT);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index e4d8067..db55f28 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -5,7 +5,7 @@
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -113,16 +113,12 @@
     private FinishRecentsRunnable mFinishLaunchHomeRunnable;
 
     // The trigger to automatically launch the current task
-    private DozeTrigger mIterateTrigger = new DozeTrigger(500, new Runnable() {
-        @Override
-        public void run() {
-            dismissRecentsToFocusedTask();
-        }
-    });
+    private int mFocusTimerDuration;
+    private DozeTrigger mIterateTrigger;
 
     /**
      * A common Runnable to finish Recents by launching Home with an animation depending on the
-     * last activity launch state.  Generally we always launch home when we exit Recents rather than
+     * last activity launch state. Generally we always launch home when we exit Recents rather than
      * just finishing the activity since we don't know what is behind Recents in the task stack.
      */
     class FinishRecentsRunnable implements Runnable {
@@ -196,13 +192,13 @@
         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) {
-            ArrayList<Task> tasks = stack.getStackTasks();
-            int taskCount = tasks.size();
             for (int j = 0; j < taskCount; j++) {
                 Task t = tasks.get(j);
                 if (t.key.id == launchState.launchedToTaskId) {
@@ -214,12 +210,12 @@
         }
 
         // Animate the SystemUI scrims into view
-        boolean hasStatusBarScrim = stack.getStackTaskCount() > 0;
+        boolean hasStatusBarScrim = taskCount > 0;
         boolean animateStatusBarScrim = launchState.launchedFromHome;
-        boolean hasNavBarScrim = (stack.getStackTaskCount() > 0) && !config.hasTransposedNavBar;
+        boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
         boolean animateNavBarScrim = true;
-        mScrimViews.prepareEnterRecentsAnimation(hasStatusBarScrim, animateStatusBarScrim, hasNavBarScrim,
-                animateNavBarScrim);
+        mScrimViews.prepareEnterRecentsAnimation(hasStatusBarScrim, animateStatusBarScrim,
+                hasNavBarScrim, animateNavBarScrim);
 
         // Keep track of whether we launched from the nav bar button or via alt-tab
         if (launchState.launchedWithAltTab) {
@@ -236,7 +232,6 @@
             MetricsLogger.count(this, "overview_source_home", 1);
         }
         // Keep track of the total stack task count
-        int taskCount = stack.getStackTaskCount();
         MetricsLogger.histogram(this, "overview_task_count", taskCount);
     }
 
@@ -357,6 +352,14 @@
         getWindow().getAttributes().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 
+        mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
+        mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
+            @Override
+            public void run() {
+                dismissRecentsToFocusedTask();
+            }
+        });
+
         // Create the home intent runnable
         Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
         homeIntent.addCategory(Intent.CATEGORY_HOME);
@@ -543,7 +546,8 @@
                     if (backward) {
                         EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
                     } else {
-                        EventBus.getDefault().send(new FocusNextTaskViewEvent());
+                        EventBus.getDefault().send(
+                                new FocusNextTaskViewEvent(false /* showTimerIndicator */));
                     }
                     mLastTabKeyEventTime = SystemClock.elapsedRealtime();
 
@@ -555,7 +559,8 @@
                 return true;
             }
             case KeyEvent.KEYCODE_DPAD_UP: {
-                EventBus.getDefault().send(new FocusNextTaskViewEvent());
+                EventBus.getDefault().send(
+                        new FocusNextTaskViewEvent(false /* showTimerIndicator */));
                 return true;
             }
             case KeyEvent.KEYCODE_DPAD_DOWN: {
@@ -564,12 +569,14 @@
             }
             case KeyEvent.KEYCODE_DEL:
             case KeyEvent.KEYCODE_FORWARD_DEL: {
-                EventBus.getDefault().send(new DismissFocusedTaskViewEvent());
+                if (event.getRepeatCount() <= 0) {
+                    EventBus.getDefault().send(new DismissFocusedTaskViewEvent());
 
-                // Keep track of deletions by keyboard
-                MetricsLogger.histogram(this, "overview_task_dismissed_source",
-                        Constants.Metrics.DismissSourceKeyboard);
-                return true;
+                    // Keep track of deletions by keyboard
+                    MetricsLogger.histogram(this, "overview_task_dismissed_source",
+                            Constants.Metrics.DismissSourceKeyboard);
+                    return true;
+                }
             }
             default:
                 break;
@@ -579,7 +586,10 @@
 
     @Override
     public void onUserInteraction() {
-        EventBus.getDefault().send(new UserInteractionEvent());
+        // TODO: Prevent creating so many events here
+        final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
+        EventBus.getDefault().send(new UserInteractionEvent(debugFlags.isFastToggleRecentsEnabled()
+                && debugFlags.isFastToggleIndicatorEnabled()));
     }
 
     @Override
@@ -603,11 +613,14 @@
 
     public final void onBusEvent(IterateRecentsEvent event) {
         if (!dismissHistory()) {
+            final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
+
             // Focus the next task
-            EventBus.getDefault().send(new FocusNextTaskViewEvent());
+            EventBus.getDefault().send(
+                    new FocusNextTaskViewEvent(debugFlags.isFastToggleRecentsEnabled()
+                            && debugFlags.isFastToggleIndicatorEnabled()));
 
             // Start dozing after the recents button is clicked
-            RecentsDebugFlags debugFlags = Recents.getDebugFlags();
             if (debugFlags.isFastToggleRecentsEnabled()) {
                 if (!mIterateTrigger.isDozing()) {
                     mIterateTrigger.startDozing();
@@ -615,6 +628,8 @@
                     mIterateTrigger.poke();
                 }
             }
+
+            MetricsLogger.action(this, MetricsLogger.ACTION_OVERVIEW_PAGE);
         }
     }
 
@@ -701,7 +716,7 @@
         intent.setComponent(intent.resolveActivity(getPackageManager()));
         TaskStackBuilder.create(this)
                 .addNextIntentWithParentStack(intent).startActivities(null,
-                new UserHandle(event.task.key.userId));
+                        new UserHandle(event.task.key.userId));
 
         // Keep track of app-info invocations
         MetricsLogger.count(this, "overview_app_info", 1);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 67135d5..61780f8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -139,7 +139,7 @@
         } else {
             // In portrait, the search bar appears on the top (which already has the inset)
             int top = searchBarBounds.isEmpty() ? topInset : 0;
-            taskStackBounds.set(windowBounds.left, searchBarBounds.bottom + top,
+            taskStackBounds.set(windowBounds.left, windowBounds.top + searchBarBounds.bottom + top,
                     windowBounds.right - rightInset, windowBounds.bottom);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index c323522..3151fd7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -27,6 +27,7 @@
 public class RecentsDebugFlags implements TunerService.Tunable {
 
     private static final String KEY_FAST_TOGGLE = "overview_fast_toggle_via_button";
+    private static final String KEY_FAST_TOGGLE_INDICATOR = "overview_fast_toggle_indicator";
     private static final String KEY_INITIAL_STATE_PAGING = "overview_initial_state_paging";
 
     public static class Static {
@@ -49,6 +50,7 @@
     }
 
     private boolean mFastToggleRecents;
+    private boolean mFastToggleIndicator;
     private boolean mInitialStatePaging;
 
     /**
@@ -58,7 +60,8 @@
     public RecentsDebugFlags(Context context) {
         // Register all our flags, this will also call onTuningChanged() for each key, which will
         // initialize the current state of each flag
-        TunerService.get(context).addTunable(this, KEY_FAST_TOGGLE, KEY_INITIAL_STATE_PAGING);
+        TunerService.get(context).addTunable(this, KEY_FAST_TOGGLE, KEY_FAST_TOGGLE_INDICATOR,
+                KEY_INITIAL_STATE_PAGING);
     }
 
     /**
@@ -69,6 +72,13 @@
     }
 
     /**
+     * @return whether we are enabling the fast toggle indicator.
+     */
+    public boolean isFastToggleIndicatorEnabled() {
+        return mFastToggleIndicator;
+    }
+
+    /**
      * @return whether the initial stack state is paging.
      */
     public boolean isInitialStatePaging() {
@@ -82,6 +92,10 @@
                 mFastToggleRecents = (newValue != null) &&
                         (Integer.parseInt(newValue) != 0);
                 break;
+            case KEY_FAST_TOGGLE_INDICATOR:
+                mFastToggleIndicator = (newValue != null) &&
+                        (Integer.parseInt(newValue) != 0);
+                break;
             case KEY_INITIAL_STATE_PAGING:
                 mInitialStatePaging = (newValue != null) &&
                         (Integer.parseInt(newValue) != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index ddeb8dc..7c25d24 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -110,9 +110,7 @@
 
         /** Preloads the next task */
         public void run() {
-            // TODO: Temporarily skip this if multi stack is enabled
-            /*
-            RecentsConfiguration config = RecentsConfiguration.getInstance();
+            RecentsConfiguration config = Recents.getConfiguration();
             if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
                 RecentsTaskLoader loader = Recents.getTaskLoader();
                 SystemServicesProxy ssp = Recents.getSystemServices();
@@ -134,7 +132,6 @@
                 launchOpts.onlyLoadPausedActivities = true;
                 loader.loadTasks(mContext, plan, launchOpts);
             }
-            */
         }
     }
 
@@ -375,7 +372,7 @@
             sInstanceLoadPlan.preloadRawTasks(topTaskHome.value);
             loader.preloadTasks(sInstanceLoadPlan, topTaskHome.value);
             TaskStack stack = sInstanceLoadPlan.getTaskStack();
-            if (stack.getStackTaskCount() > 0) {
+            if (stack.getTaskCount() > 0) {
                 // We try and draw the thumbnail transition bitmap in parallel before
                 // toggle/show recents is called
                 preCacheThumbnailTransitionBitmapAsync(topTask, stack, mDummyStackView);
@@ -406,7 +403,7 @@
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
-        if (focusedStack == null || focusedStack.getStackTaskCount() == 0) return;
+        if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
 
         ActivityManager.RunningTaskInfo runningTask = ssp.getTopMostTask();
         // Return early if there is no running task
@@ -458,7 +455,7 @@
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
-        if (focusedStack == null || focusedStack.getStackTaskCount() == 0) return;
+        if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
 
         ActivityManager.RunningTaskInfo runningTask = ssp.getTopMostTask();
         // Return early if there is no running task (can't determine affiliated tasks in this case)
@@ -848,7 +845,7 @@
             return;
         }
 
-        boolean hasRecentTasks = stack.getStackTaskCount() > 0;
+        boolean hasRecentTasks = stack.getTaskCount() > 0;
         boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks;
 
         if (useThumbnailTransition) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java b/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
index b0c8ff3..212c7f4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
@@ -290,6 +290,28 @@
     }
 
     /**
+     * An event that can be reusable, only used for situations where we want to reduce memory
+     * allocations when events are sent frequently (ie. on scroll).
+     */
+    public static class ReusableEvent extends Event {
+
+        private int mDispatchCount;
+
+        protected ReusableEvent() {}
+
+        @Override
+        void onPostDispatch() {
+            super.onPostDispatch();
+            mDispatchCount++;
+        }
+
+        @Override
+        protected Object clone() throws CloneNotSupportedException {
+            throw new CloneNotSupportedException();
+        }
+    }
+
+    /**
      * An inter-process event super class that allows us to track user state across subscriber
      * invocations.
      */
@@ -770,8 +792,11 @@
         event.onPreDispatch();
 
         // We need to clone the list in case a subscriber unregisters itself during traversal
+        // TODO: Investigate whether we can skip the object creation here
         eventHandlers = (ArrayList<EventHandler>) eventHandlers.clone();
-        for (final EventHandler eventHandler : eventHandlers) {
+        int eventHandlerCount = eventHandlers.size();
+        for (int i = 0; i < eventHandlerCount; i++) {
+            final EventHandler eventHandler = eventHandlers.get(i);
             if (eventHandler.subscriber.getReference() != null) {
                 if (event.requiresPost) {
                     mHandler.post(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/StackViewScrolledEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/StackViewScrolledEvent.java
index cb5011a..ad9feb6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/StackViewScrolledEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/StackViewScrolledEvent.java
@@ -16,16 +16,21 @@
 
 package com.android.systemui.recents.events.ui;
 
+import android.util.MutableInt;
 import com.android.systemui.recents.events.EventBus;
 
 /**
  * This is sent whenever a new scroll gesture happens on a stack view.
  */
-public class StackViewScrolledEvent extends EventBus.Event {
+public class StackViewScrolledEvent extends EventBus.ReusableEvent {
 
-    public final int yMovement;
+    public final MutableInt yMovement;
 
-    public StackViewScrolledEvent(int yMovement) {
-        this.yMovement = yMovement;
+    public StackViewScrolledEvent() {
+        yMovement = new MutableInt(0);
+    }
+
+    public void updateY(int y) {
+        yMovement.value = y;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
index 6e6cd84..5a132c2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
@@ -22,5 +22,10 @@
  * This is sent whenever the user interacts with the activity.
  */
 public class UserInteractionEvent extends EventBus.Event {
-    // Simple event
+
+    public final boolean showTimerIndicator;
+
+    public UserInteractionEvent(boolean showTimerIndicator) {
+        this.showTimerIndicator = showTimerIndicator;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragDropTargetChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragDropTargetChangedEvent.java
index 21321f2..b85ddac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragDropTargetChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragDropTargetChangedEvent.java
@@ -25,6 +25,7 @@
  */
 public class DragDropTargetChangedEvent extends EventBus.Event {
 
+    // The task that is currently being dragged
     public final Task task;
     public final DropTarget dropTarget;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
index 171ab5e..def4ae1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
@@ -22,5 +22,10 @@
  * Focuses the next task view in the stack.
  */
 public class FocusNextTaskViewEvent extends EventBus.Event {
-    // Simple event
+
+    public final boolean showTimerIndicator;
+
+    public FocusNextTaskViewEvent(boolean showTimerIndicator) {
+        this.showTimerIndicator = showTimerIndicator;
+    }
 }
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 f0fa1da..80597bc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
@@ -26,6 +26,7 @@
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
+import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.events.EventBus;
@@ -129,6 +130,9 @@
             SystemServicesProxy ssp = Recents.getSystemServices();
             ssp.startActivityFromRecents(v.getContext(), task.key.id, task.title,
                     ActivityOptions.makeBasic());
+
+            MetricsLogger.action(v.getContext(), MetricsLogger.ACTION_OVERVIEW_SELECT,
+                    task.key.getComponent().toString());
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
index a2f5159..39bb6ca 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
@@ -28,6 +28,7 @@
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.LinearLayout;
+import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivity;
@@ -99,6 +100,8 @@
         });
         mAdapter.updateTasks(getContext(), stack);
         mIsVisible = true;
+
+        MetricsLogger.visible(mRecyclerView.getContext(), MetricsLogger.OVERVIEW_HISTORY);
     }
 
     /**
@@ -129,6 +132,8 @@
             setVisibility(View.INVISIBLE);
         }
         mIsVisible = false;
+
+        MetricsLogger.hidden(mRecyclerView.getContext(), MetricsLogger.OVERVIEW_HISTORY);
     }
 
     /**
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 3406da9..adc1e92 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -59,7 +59,9 @@
 import android.util.Pair;
 import android.view.Display;
 import android.view.IDockedStackListener;
+import android.view.View;
 import android.view.WindowManager;
+import android.view.WindowManager.KeyboardShortcutsReceiver;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityManager;
 import com.android.internal.app.AssistUtils;
@@ -306,11 +308,13 @@
     }
 
     /** Docks a task to the side of the screen and starts it. */
-    public void startTaskInDockedMode(int taskId, int createMode) {
+    public void startTaskInDockedMode(Context context, View view, int taskId, int createMode) {
         if (mIam == null) return;
 
         try {
-            final ActivityOptions options = ActivityOptions.makeBasic();
+            // TODO: Determine what animation we want for the incoming task
+            final ActivityOptions options = ActivityOptions.makeThumbnailAspectScaleUpAnimation(
+                    view, null, 0, 0, view.getWidth(), view.getHeight(), null, null);
             options.setDockCreateMode(createMode);
             options.setLaunchStackId(DOCKED_STACK_ID);
             mIam.startActivityFromRecents(taskId, options.toBundle());
@@ -365,7 +369,7 @@
     }
 
     /**
-     * @return whether there are any docked tasks.
+     * @return whether there are any docked tasks for the current user.
      */
     public boolean hasDockedTask() {
         if (mIam == null) return false;
@@ -373,6 +377,9 @@
         ActivityManager.StackInfo stackInfo = null;
         try {
             stackInfo = mIam.getStackInfo(DOCKED_STACK_ID);
+            if (stackInfo != null && stackInfo.userId != getCurrentUser()) {
+                return false;
+            }
         } catch (RemoteException e) {
             e.printStackTrace();
         }
@@ -915,4 +922,20 @@
             e.printStackTrace();
         }
     }
+
+    /**
+     * Calculates the size of the dock divider in the current orientation.
+     */
+    public int getDockedDividerSize(Context context) {
+        Resources res = context.getResources();
+        int dividerWindowWidth = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_thickness);
+        int dividerInsets = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_insets);
+        return dividerWindowWidth - 2 * dividerInsets;
+    }
+
+    public void requestKeyboardShortcuts(Context context, KeyboardShortcutsReceiver receiver) {
+        mWm.requestAppKeyboardShortcuts(receiver);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index 2bf2ccb..f3c4cc3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -18,13 +18,49 @@
 
 import android.animation.Animator;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.util.ArraySet;
+import android.util.IntProperty;
+import android.util.Property;
 import android.view.View;
 import android.view.ViewParent;
+import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.views.TaskViewTransform;
+
+import java.util.Collections;
+import java.util.List;
 
 /* Common code */
 public class Utilities {
 
+    public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
+            new IntProperty<Drawable>("drawableAlpha") {
+                @Override
+                public void setValue(Drawable object, int alpha) {
+                    object.setAlpha(alpha);
+                }
+
+                @Override
+                public Integer get(Drawable object) {
+                    return object.getAlpha();
+                }
+            };
+
+    public static final Property<Drawable, Rect> DRAWABLE_RECT =
+            new Property<Drawable, Rect>(Rect.class, "drawableBounds") {
+                @Override
+                public void set(Drawable object, Rect bounds) {
+                    object.setBounds(bounds);
+                }
+
+                @Override
+                public Rect get(Drawable object) {
+                    return object.getBounds();
+                }
+            };
+
     /**
      * @return the first parent walking up the view hierarchy that has the given class type.
      *
@@ -41,6 +77,28 @@
         return null;
     }
 
+    /**
+     * Initializes the {@param setOut} with the given object.
+     */
+    public static <T> ArraySet<T> objectToSet(T obj, ArraySet<T> setOut) {
+        setOut.clear();
+        if (obj != null) {
+            setOut.add(obj);
+        }
+        return setOut;
+    }
+
+    /**
+     * Replaces the contents of {@param setOut} with the contents of the {@param array}.
+     */
+    public static <T> ArraySet<T> arrayToSet(T[] array, ArraySet<T> setOut) {
+        setOut.clear();
+        if (array != null) {
+            Collections.addAll(setOut, array);
+        }
+        return setOut;
+    }
+
     /** Scales a rect about its centroid */
     public static void scaleRectAboutCenter(RectF r, float scale) {
         if (scale != 1.0f) {
@@ -97,4 +155,22 @@
             animator.cancel();
         }
     }
+
+    /**
+     * Updates {@param transforms} to be the same size as {@param tasks}.
+     */
+    public static void matchTaskListSize(List<Task> tasks, List<TaskViewTransform> transforms) {
+        // We can reuse the task transforms where possible to reduce object allocation
+        int taskTransformCount = transforms.size();
+        int taskCount = tasks.size();
+        if (taskTransformCount < taskCount) {
+            // If there are less transforms than tasks, then add as many transforms as necessary
+            for (int i = taskTransformCount; i < taskCount; i++) {
+                transforms.add(new TaskViewTransform());
+            }
+        } else if (taskTransformCount > taskCount) {
+            // If there are more transforms than tasks, then just subset the transform list
+            transforms.subList(taskCount, taskTransformCount).clear();
+        }
+    }
 }
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 d8dfce5..822ad77 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,9 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArraySet;
+
 import com.android.systemui.Prefs;
+import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -120,6 +122,8 @@
             preloadRawTasks(isTopTaskHome);
         }
 
+        String dismissDescFormat = mContext.getString(
+                R.string.accessibility_recents_item_will_be_dismissed);
         long lastStackActiveTime = Prefs.getLong(mContext,
                 Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, 0);
         long newLastStackActiveTime = -1;
@@ -143,6 +147,7 @@
             // Load the title, icon, and color
             String title = loader.getAndUpdateActivityTitle(taskKey, t.taskDescription);
             String contentDescription = loader.getAndUpdateContentDescription(taskKey, title, res);
+            String dismissDescription = String.format(dismissDescFormat, contentDescription);
             Drawable icon = isStackTask
                     ? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, res, false)
                     : null;
@@ -151,8 +156,8 @@
 
             // Add the task to the stack
             Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon,
-                    thumbnail, title, contentDescription, activityColor, !isStackTask,
-                    t.bounds, t.taskDescription);
+                    thumbnail, title, contentDescription, dismissDescription, activityColor,
+                    !isStackTask, t.bounds, t.taskDescription);
 
             allTasks.add(task);
         }
@@ -219,7 +224,7 @@
     /** Returns whether there are any tasks in any stacks. */
     public boolean hasTasks() {
         if (mStack != null) {
-            return mStack.getStackTaskCount() > 0;
+            return mStack.getTaskCount() > 0;
         }
         return false;
     }
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 f7e2b9d..29e7077 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -54,6 +54,8 @@
         public long firstActiveTime;
         public long lastActiveTime;
 
+        private int mHashCode;
+
         public TaskKey(int id, int stackId, Intent intent, int userId, long firstActiveTime,
                 long lastActiveTime) {
             this.id = id;
@@ -62,6 +64,12 @@
             this.userId = userId;
             this.firstActiveTime = firstActiveTime;
             this.lastActiveTime = lastActiveTime;
+            updateHashCode();
+        }
+
+        public void setStackId(int stackId) {
+            this.stackId = stackId;
+            updateHashCode();
         }
 
         public ComponentName getComponent() {
@@ -79,7 +87,7 @@
 
         @Override
         public int hashCode() {
-            return Objects.hash(id, stackId, userId);
+            return mHashCode;
         }
 
         @Override
@@ -90,6 +98,10 @@
                     + "lat: " + lastActiveTime + ", "
                     + getComponent().getPackageName();
         }
+
+        private void updateHashCode() {
+            mHashCode = Objects.hash(id, stackId, userId);
+        }
     }
 
     public TaskKey key;
@@ -113,6 +125,7 @@
     public Bitmap thumbnail;
     public String title;
     public String contentDescription;
+    public String dismissDescription;
     public int colorPrimary;
     public boolean useLightOnPrimaryColor;
 
@@ -139,9 +152,9 @@
     }
 
     public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon,
-                Bitmap thumbnail, String title, String contentDescription, int colorPrimary,
-                boolean isHistorical, Rect bounds,
-                ActivityManager.TaskDescription taskDescription) {
+                Bitmap thumbnail, String title, String contentDescription,
+                String dismissDescription, int colorPrimary, boolean isHistorical,
+                Rect bounds, ActivityManager.TaskDescription taskDescription) {
         boolean isInAffiliationGroup = (affiliationTaskId != key.id);
         boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0);
         this.key = key;
@@ -151,6 +164,7 @@
         this.thumbnail = thumbnail;
         this.title = title;
         this.contentDescription = contentDescription;
+        this.dismissDescription = dismissDescription;
         this.colorPrimary = hasAffiliationGroupColor ? affiliationColor : colorPrimary;
         this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary,
                 Color.WHITE) > 3f;
@@ -169,6 +183,7 @@
         this.thumbnail = o.thumbnail;
         this.title = o.title;
         this.contentDescription = o.contentDescription;
+        this.dismissDescription = o.dismissDescription;
         this.colorPrimary = o.colorPrimary;
         this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
         this.bounds = o.bounds;
@@ -201,7 +216,7 @@
      * Updates the stack id of this task.
      */
     public void setStackId(int stackId) {
-        key.stackId = stackId;
+        key.setStackId(stackId);
         int callbackCount = mCallbacks.size();
         for (int i = 0; i < callbackCount; i++) {
             mCallbacks.get(i).onTaskStackIdChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java
index 288f07c..2109376 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java
@@ -1,7 +1,8 @@
 package com.android.systemui.recents.model;
 
+import android.util.ArrayMap;
+
 import java.util.ArrayList;
-import java.util.HashMap;
 
 /** Represents a grouping of tasks witihin a stack. */
 public class TaskGrouping {
@@ -11,7 +12,7 @@
 
     Task.TaskKey mFrontMostTaskKey;
     ArrayList<Task.TaskKey> mTaskKeys = new ArrayList<Task.TaskKey>();
-    HashMap<Task.TaskKey, Integer> mTaskKeyIndices = new HashMap<Task.TaskKey, Integer>();
+    ArrayMap<Task.TaskKey, Integer> mTaskKeyIndices = new ArrayMap<>();
 
     /** Creates a group with a specified affiliation. */
     public TaskGrouping(int affiliation) {
@@ -94,9 +95,9 @@
             return;
         }
 
+        int taskCount = mTaskKeys.size();
         mFrontMostTaskKey = mTaskKeys.get(mTaskKeys.size() - 1);
         mTaskKeyIndices.clear();
-        int taskCount = mTaskKeys.size();
         for (int i = 0; i < taskCount; i++) {
             Task.TaskKey k = mTaskKeys.get(i);
             mTaskKeyIndices.put(k, i);
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 856200d..327cdf8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -16,16 +16,27 @@
 
 package com.android.systemui.recents.model;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.RectEvaluator;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.SparseArray;
+import android.view.animation.Interpolator;
+import com.android.internal.policy.DockedDividerUtils;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.misc.NamedCounter;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -35,8 +46,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Random;
 
@@ -44,6 +53,11 @@
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
 
 
 /**
@@ -59,17 +73,14 @@
  */
 class FilteredTaskList {
 
-    private static final String TAG = "FilteredTaskList";
-    private static final boolean DEBUG = false;
-
     ArrayList<Task> mTasks = new ArrayList<>();
     ArrayList<Task> mFilteredTasks = new ArrayList<>();
-    HashMap<Task.TaskKey, Integer> mTaskIndices = new HashMap<>();
+    ArrayMap<Task.TaskKey, Integer> mTaskIndices = new ArrayMap<>();
     TaskFilter mFilter;
 
     /** Sets the task filter, saving the current touch state */
     boolean setFilter(TaskFilter filter) {
-        ArrayList<Task> prevFilteredTasks = new ArrayList<Task>(mFilteredTasks);
+        ArrayList<Task> prevFilteredTasks = new ArrayList<>(mFilteredTasks);
         mFilter = filter;
         updateFilteredTasks();
         if (!prevFilteredTasks.equals(mFilteredTasks)) {
@@ -180,8 +191,8 @@
 
     /** Updates the mapping of tasks to indices. */
     private void updateFilteredTaskIndices() {
-        mTaskIndices.clear();
         int taskCount = mFilteredTasks.size();
+        mTaskIndices.clear();
         for (int i = 0; i < taskCount; i++) {
             Task t = mFilteredTasks.get(i);
             mTaskIndices.put(t.key, i);
@@ -229,30 +240,36 @@
     public static class DockState implements DropTarget {
 
         private static final int DOCK_AREA_ALPHA = 192;
-        public static final DockState NONE = new DockState(-1, 96, null, null);
-        public static final DockState LEFT = new DockState(
+        public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, null, null, null);
+        public static final DockState LEFT = new DockState(DOCKED_LEFT,
                 DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA,
-                new RectF(0, 0, 0.15f, 1), new RectF(0, 0, 0.15f, 1));
-        public static final DockState TOP = new DockState(
+                new RectF(0, 0, 0.125f, 1), new RectF(0, 0, 0.125f, 1),
+                new RectF(0, 0, 0.5f, 1));
+        public static final DockState TOP = new DockState(DOCKED_TOP,
                 DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA,
-                new RectF(0, 0, 1, 0.15f), new RectF(0, 0, 1, 0.15f));
-        public static final DockState RIGHT = new DockState(
+                new RectF(0, 0, 1, 0.125f), new RectF(0, 0, 1, 0.125f),
+                new RectF(0, 0, 1, 0.5f));
+        public static final DockState RIGHT = new DockState(DOCKED_RIGHT,
                 DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA,
-                new RectF(0.85f, 0, 1, 1), new RectF(0.85f, 0, 1, 1));
-        public static final DockState BOTTOM = new DockState(
+                new RectF(0.875f, 0, 1, 1), new RectF(0.875f, 0, 1, 1),
+                new RectF(0.5f, 0, 1, 1));
+        public static final DockState BOTTOM = new DockState(DOCKED_BOTTOM,
                 DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA,
-                new RectF(0, 0.85f, 1, 1), new RectF(0, 0.85f, 1, 1));
+                new RectF(0, 0.875f, 1, 1), new RectF(0, 0.875f, 1, 1),
+                new RectF(0, 0.5f, 1, 1));
 
         @Override
-        public boolean acceptsDrop(int x, int y, int width, int height) {
-            return touchAreaContainsPoint(width, height, x, y);
+        public boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget) {
+            return isCurrentTarget
+                    ? areaContainsPoint(expandedTouchDockArea, width, height, x, y)
+                    : areaContainsPoint(touchArea, width, height, x, y);
         }
 
         // Represents the view state of this dock state
         public class ViewState {
             public final int dockAreaAlpha;
             public final ColorDrawable dockAreaOverlay;
-            private ObjectAnimator dockAreaOverlayAnimator;
+            private AnimatorSet dockAreaOverlayAnimator;
 
             private ViewState(int alpha) {
                 dockAreaAlpha = alpha;
@@ -261,56 +278,130 @@
             }
 
             /**
-             * Creates a new alpha animation.
+             * Creates a new bounds and alpha animation.
              */
-            public void startAlphaAnimation(int alpha, int duration) {
+            public void startAnimation(Rect bounds, int alpha, int duration,
+                    Interpolator interpolator, boolean animateAlpha, boolean animateBounds) {
+                if (dockAreaOverlayAnimator != null) {
+                    dockAreaOverlayAnimator.cancel();
+                }
+
+                ArrayList<Animator> animators = new ArrayList<>();
                 if (dockAreaOverlay.getAlpha() != alpha) {
-                    if (dockAreaOverlayAnimator != null) {
-                        dockAreaOverlayAnimator.cancel();
+                    if (animateAlpha) {
+                        animators.add(ObjectAnimator.ofInt(dockAreaOverlay,
+                                Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), alpha));
+                    } else {
+                        dockAreaOverlay.setAlpha(alpha);
                     }
-                    dockAreaOverlayAnimator = ObjectAnimator.ofInt(dockAreaOverlay, "alpha", alpha);
+                }
+                if (bounds != null && !dockAreaOverlay.getBounds().equals(bounds)) {
+                    if (animateBounds) {
+                        PropertyValuesHolder prop = PropertyValuesHolder.ofObject(
+                                Utilities.DRAWABLE_RECT, new RectEvaluator(new Rect()),
+                                dockAreaOverlay.getBounds(), bounds);
+                        animators.add(ObjectAnimator.ofPropertyValuesHolder(dockAreaOverlay, prop));
+                    } else {
+                        dockAreaOverlay.setBounds(bounds);
+                    }
+                }
+                if (!animators.isEmpty()) {
+                    dockAreaOverlayAnimator = new AnimatorSet();
+                    dockAreaOverlayAnimator.playTogether(animators);
                     dockAreaOverlayAnimator.setDuration(duration);
+                    dockAreaOverlayAnimator.setInterpolator(interpolator);
                     dockAreaOverlayAnimator.start();
                 }
             }
         }
 
+        public final int dockSide;
         public final int createMode;
         public final ViewState viewState;
-        private final RectF dockArea;
         private final RectF touchArea;
+        private final RectF dockArea;
+        private final RectF expandedTouchDockArea;
 
         /**
          * @param createMode used to pass to ActivityManager to dock the task
          * @param touchArea the area in which touch will initiate this dock state
          * @param dockArea the visible dock area
+         * @param expandedTouchDockArea the areain which touch will continue to dock after entering
+         *                              the initial touch area.  This is also the new dock area to
+         *                              draw.
          */
-        DockState(int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea) {
+        DockState(int dockSide, int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea,
+                  RectF expandedTouchDockArea) {
+            this.dockSide = dockSide;
             this.createMode = createMode;
             this.viewState = new ViewState(dockAreaAlpha);
             this.dockArea = dockArea;
             this.touchArea = touchArea;
+            this.expandedTouchDockArea = expandedTouchDockArea;
         }
 
         /**
-         * Returns whether {@param x} and {@param y} are contained in the touch area scaled to the
+         * Returns whether {@param x} and {@param y} are contained in the area scaled to the
          * given {@param width} and {@param height}.
          */
-        public boolean touchAreaContainsPoint(int width, int height, float x, float y) {
-            int left = (int) (touchArea.left * width);
-            int top = (int) (touchArea.top * height);
-            int right = (int) (touchArea.right * width);
-            int bottom = (int) (touchArea.bottom * height);
+        public boolean areaContainsPoint(RectF area, int width, int height, float x, float y) {
+            int left = (int) (area.left * width);
+            int top = (int) (area.top * height);
+            int right = (int) (area.right * width);
+            int bottom = (int) (area.bottom * height);
             return x >= left && y >= top && x <= right && y <= bottom;
         }
 
         /**
          * Returns the docked task bounds with the given {@param width} and {@param height}.
          */
-        public Rect getDockedBounds(int width, int height) {
+        public Rect getPreDockedBounds(int width, int height) {
             return new Rect((int) (dockArea.left * width), (int) (dockArea.top * height),
                     (int) (dockArea.right * width), (int) (dockArea.bottom * height));
         }
+
+        /**
+         * Returns the expanded docked task bounds with the given {@param width} and
+         * {@param height}.
+         */
+        public Rect getDockedBounds(int width, int height, int dividerSize, Rect insets,
+                Resources res) {
+            // Calculate the docked task bounds
+            boolean isHorizontalDivision =
+                    res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
+            int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
+                    insets, width, height, dividerSize);
+            Rect newWindowBounds = new Rect();
+            DockedDividerUtils.calculateBoundsForPosition(position, dockSide, newWindowBounds,
+                    width, height, dividerSize);
+            return newWindowBounds;
+        }
+
+        /**
+         * Returns the task stack bounds with the given {@param width} and
+         * {@param height}.
+         */
+        public Rect getDockedTaskStackBounds(int width, int height, int dividerSize, Rect insets,
+                Resources res) {
+            RecentsConfiguration config = Recents.getConfiguration();
+
+            // Calculate the inverse docked task bounds
+            boolean isHorizontalDivision =
+                    res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
+            int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
+                    insets, width, height, dividerSize);
+            Rect newWindowBounds = new Rect();
+            DockedDividerUtils.calculateBoundsForPosition(position,
+                    DockedDividerUtils.invertDockSide(dockSide), newWindowBounds, width, height,
+                    dividerSize);
+
+            // Calculate the task stack bounds from the new window bounds
+            Rect searchBarSpaceBounds = new Rect();
+            Rect taskStackBounds = new Rect();
+            config.getTaskStackBounds(newWindowBounds, insets.top, insets.right,
+                    searchBarSpaceBounds, taskStackBounds);
+            return taskStackBounds;
+        }
     }
 
     // A comparator that sorts tasks by their last active time
@@ -344,7 +435,7 @@
     TaskStackCallbacks mCb;
 
     ArrayList<TaskGrouping> mGroups = new ArrayList<>();
-    HashMap<Integer, TaskGrouping> mAffinitiesGroups = new HashMap<>();
+    ArrayMap<Integer, TaskGrouping> mAffinitiesGroups = new ArrayMap<>();
 
     public TaskStack() {
         // Ensure that we only show non-docked tasks
@@ -446,6 +537,7 @@
                 mCb.onHistoryTaskRemoved(this, t);
             }
         }
+        mRawTaskList.remove(t);
     }
 
     /**
@@ -456,8 +548,8 @@
      */
     public void setTasks(List<Task> tasks, boolean notifyStackChanges) {
         // Compute a has set for each of the tasks
-        HashMap<Task.TaskKey, Task> currentTasksMap = createTaskKeyMapFromList(mRawTaskList);
-        HashMap<Task.TaskKey, Task> newTasksMap = createTaskKeyMapFromList(tasks);
+        ArrayMap<Task.TaskKey, Task> currentTasksMap = createTaskKeyMapFromList(mRawTaskList);
+        ArrayMap<Task.TaskKey, Task> newTasksMap = createTaskKeyMapFromList(tasks);
 
         ArrayList<Task> newTasks = new ArrayList<>();
 
@@ -588,16 +680,32 @@
     }
 
     /**
-     * Returns the number of tasks in the active stack.
+     * Returns the number of stack and freeform tasks.
      */
-    public int getStackTaskCount() {
+    public int getTaskCount() {
         return mStackTaskList.size();
     }
 
     /**
-     * Returns the number of freeform tasks in the active stack.
+     * Returns the number of stack tasks.
      */
-    public int getStackTaskFreeformCount() {
+    public int getStackTaskCount() {
+        ArrayList<Task> tasks = mStackTaskList.getTasks();
+        int stackCount = 0;
+        int taskCount = tasks.size();
+        for (int i = 0; i < taskCount; i++) {
+            Task task = tasks.get(i);
+            if (!task.isFreeformTask()) {
+                stackCount++;
+            }
+        }
+        return stackCount;
+    }
+
+    /**
+     * Returns the number of freeform tasks.
+     */
+    public int getFreeformTaskCount() {
         ArrayList<Task> tasks = mStackTaskList.getTasks();
         int freeformCount = 0;
         int taskCount = tasks.size();
@@ -664,7 +772,7 @@
      */
     public void createAffiliatedGroupings(Context context) {
         if (RecentsDebugFlags.Static.EnableSimulatedTaskGroups) {
-            HashMap<Task.TaskKey, Task> taskMap = new HashMap<Task.TaskKey, Task>();
+            ArrayMap<Task.TaskKey, Task> taskMap = new ArrayMap<>();
             // Sort all tasks by increasing firstActiveTime of the task
             ArrayList<Task> tasks = mStackTaskList.getTasks();
             Collections.sort(tasks, new Comparator<Task>() {
@@ -729,7 +837,7 @@
             mStackTaskList.set(tasks);
         } else {
             // Create the task groups
-            HashMap<Task.TaskKey, Task> tasksMap = new HashMap<>();
+            ArrayMap<Task.TaskKey, Task> tasksMap = new ArrayMap<>();
             ArrayList<Task> tasks = mStackTaskList.getTasks();
             int taskCount = tasks.size();
             for (int i = 0; i < taskCount; i++) {
@@ -773,12 +881,12 @@
      * Computes the components of tasks in this stack that have been removed as a result of a change
      * in the specified package.
      */
-    public HashSet<ComponentName> computeComponentsRemoved(String packageName, int userId) {
+    public ArraySet<ComponentName> computeComponentsRemoved(String packageName, int userId) {
         // Identify all the tasks that should be removed as a result of the package being removed.
         // Using a set to ensure that we callback once per unique component.
         SystemServicesProxy ssp = Recents.getSystemServices();
-        HashSet<ComponentName> existingComponents = new HashSet<>();
-        HashSet<ComponentName> removedComponents = new HashSet<>();
+        ArraySet<ComponentName> existingComponents = new ArraySet<>();
+        ArraySet<ComponentName> removedComponents = new ArraySet<>();
         ArrayList<Task.TaskKey> taskKeys = getTaskKeys();
         for (Task.TaskKey t : taskKeys) {
             // Skip if this doesn't apply to the current user
@@ -816,8 +924,8 @@
     /**
      * Given a list of tasks, returns a map of each task's key to the task.
      */
-    private HashMap<Task.TaskKey, Task> createTaskKeyMapFromList(List<Task> tasks) {
-        HashMap<Task.TaskKey, Task> map = new HashMap<>();
+    private ArrayMap<Task.TaskKey, Task> createTaskKeyMapFromList(List<Task> tasks) {
+        ArrayMap<Task.TaskKey, Task> map = new ArrayMap<>(tasks.size());
         int taskCount = tasks.size();
         for (int i = 0; i < taskCount; i++) {
             Task task = tasks.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index b8bbf51..5a72897 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -58,6 +58,7 @@
     void setAlpha(float alpha) {
         if (Float.compare(alpha, mAlpha) != 0) {
             mAlpha = alpha;
+            // TODO, If both clip and alpha change in the same frame, only invalidate once
             mSourceView.invalidateOutline();
         }
     }
@@ -79,6 +80,7 @@
                 mSourceView.getHeight() - Math.max(0, mClipRect.bottom));
         if (!mLastClipBounds.equals(mClipBounds)) {
             mSourceView.setClipBounds(mClipBounds);
+            // TODO, If both clip and alpha change in the same frame, only invalidate once
             mSourceView.invalidateOutline();
             mLastClipBounds.set(mClipBounds);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java b/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
index 8ae00a7..3ad368c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
@@ -25,5 +25,5 @@
      * Returns whether this target can accept this drop.  The x,y are relative to the top level
      * RecentsView, and the width/height are of the RecentsView.
      */
-    boolean acceptsDrop(int x, int y, int width, int height);
+    boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 890713e..491c4c2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -17,13 +17,12 @@
 package com.android.systemui.recents.views;
 
 import android.content.Context;
-import android.graphics.Rect;
 import android.graphics.RectF;
+import android.util.ArrayMap;
 import com.android.systemui.R;
 import com.android.systemui.recents.model.Task;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -32,7 +31,7 @@
 public class FreeformWorkspaceLayoutAlgorithm {
 
     // Optimization, allows for quick lookup of task -> rect
-    private HashMap<Task.TaskKey, RectF> mTaskRectMap = new HashMap<>();
+    private ArrayMap<Task.TaskKey, RectF> mTaskRectMap = new ArrayMap<>();
 
     private int mTaskPadding;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index fdb0d32..b363ed5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -165,7 +165,7 @@
             int taskIndexFromFront = 0;
             int taskIndex = stack.indexOfStackTask(task);
             if (taskIndex > -1) {
-                taskIndexFromFront = stack.getStackTaskCount() - taskIndex - 1;
+                taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
             }
             EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
         } else {
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 e28e2b3..e727652 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -59,13 +59,14 @@
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
@@ -76,8 +77,7 @@
  */
 public class RecentsView extends FrameLayout {
 
-    private static final String TAG = "RecentsView";
-    private static final boolean DEBUG = false;
+    private static final int DOCK_AREA_OVERLAY_TRANSITION_DURATION = 135;
 
     private final Handler mHandler;
 
@@ -89,15 +89,10 @@
     private boolean mAwaitingFirstLayout = true;
     private boolean mLastTaskLaunchedWasFreeform;
     private Rect mSystemInsets = new Rect();
+    private int mDividerSize;
 
     private RecentsTransitionHelper mTransitionHelper;
     private RecentsViewTouchHandler mTouchHandler;
-    private TaskStack.DockState[] mVisibleDockStates = {
-            TaskStack.DockState.LEFT,
-            TaskStack.DockState.TOP,
-            TaskStack.DockState.RIGHT,
-            TaskStack.DockState.BOTTOM,
-    };
 
     private final Interpolator mFastOutSlowInInterpolator;
     private final Interpolator mFastOutLinearInInterpolator;
@@ -118,12 +113,15 @@
     public RecentsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         setWillNotDraw(false);
+
+        SystemServicesProxy ssp = Recents.getSystemServices();
         mHandler = new Handler();
         mTransitionHelper = new RecentsTransitionHelper(getContext(), mHandler);
         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);
+        mDividerSize = ssp.getDockedDividerSize(context);
         mTouchHandler = new RecentsViewTouchHandler(this);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
 
@@ -163,7 +161,7 @@
         }
 
         // Update the top level view's visibilities
-        if (stack.getStackTaskCount() > 0) {
+        if (stack.getTaskCount() > 0) {
             hideEmptyView();
         } else {
             showEmptyView();
@@ -314,7 +312,7 @@
     @Override
     protected void onAttachedToWindow() {
         EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
-        EventBus.getDefault().register(mTouchHandler, RecentsActivity.EVENT_BUS_PRIORITY + 1);
+        EventBus.getDefault().register(mTouchHandler, RecentsActivity.EVENT_BUS_PRIORITY + 2);
         super.onAttachedToWindow();
     }
 
@@ -431,8 +429,9 @@
     @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
-        for (int i = mVisibleDockStates.length - 1; i >= 0; i--) {
-            Drawable d = mVisibleDockStates[i].viewState.dockAreaOverlay;
+        ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
+        for (int i = visDockStates.size() - 1; i >= 0; i--) {
+            Drawable d = visDockStates.get(i).viewState.dockAreaOverlay;
             if (d.getAlpha() > 0) {
                 d.draw(canvas);
             }
@@ -441,8 +440,9 @@
 
     @Override
     protected boolean verifyDrawable(Drawable who) {
-        for (int i = mVisibleDockStates.length - 1; i >= 0; i--) {
-            Drawable d = mVisibleDockStates[i].viewState.dockAreaOverlay;
+        ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
+        for (int i = visDockStates.size() - 1; i >= 0; i--) {
+            Drawable d = visDockStates.get(i).viewState.dockAreaOverlay;
             if (d == who) {
                 return true;
             }
@@ -470,52 +470,76 @@
 
     public final void onBusEvent(DragStartEvent event) {
         updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
-                TaskStack.DockState.NONE.viewState.dockAreaAlpha);
+                true /* isDefaultDockState */, TaskStack.DockState.NONE.viewState.dockAreaAlpha,
+                true /* animateAlpha */, false /* animateBounds */);
     }
 
     public final void onBusEvent(DragDropTargetChangedEvent event) {
         if (event.dropTarget == null || !(event.dropTarget instanceof TaskStack.DockState)) {
             updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
-                    TaskStack.DockState.NONE.viewState.dockAreaAlpha);
+                    true /* isDefaultDockState */, TaskStack.DockState.NONE.viewState.dockAreaAlpha,
+                    true /* animateAlpha */, true /* animateBounds */);
         } else {
             final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
-            updateVisibleDockRegions(new TaskStack.DockState[] {dockState}, -1);
+            updateVisibleDockRegions(new TaskStack.DockState[] {dockState},
+                    false /* isDefaultDockState */, -1, true /* animateAlpha */,
+                    true /* animateBounds */);
         }
     }
 
     public final void onBusEvent(final DragEndEvent event) {
-        // Animate the overlay alpha back to 0
-        updateVisibleDockRegions(null, -1);
-
         // Handle the case where we drop onto a dock region
         if (event.dropTarget instanceof TaskStack.DockState) {
-            TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
+            final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
+
+            // Hide the dock region
+            updateVisibleDockRegions(null, false /* isDefaultDockState */, -1,
+                    false /* animateAlpha */, false /* animateBounds */);
+
             TaskStackLayoutAlgorithm stackLayout = mTaskStackView.getStackAlgorithm();
             TaskStackViewScroller stackScroller = mTaskStackView.getScroller();
             TaskViewTransform tmpTransform = new TaskViewTransform();
 
+            // We translated the view but we need to animate it back from the current layout-space
+            // rect to its final layout-space rect
+            int x = (int) event.taskView.getTranslationX();
+            int y = (int) event.taskView.getTranslationY();
+            Rect taskViewRect = new Rect(event.taskView.getLeft(), event.taskView.getTop(),
+                    event.taskView.getRight(), event.taskView.getBottom());
+            taskViewRect.offset(x, y);
+            event.taskView.setTranslationX(0);
+            event.taskView.setTranslationY(0);
+            event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
+                    taskViewRect.right, taskViewRect.bottom);
+
             // Remove the task view after it is docked
+            mTaskStackView.updateLayout(false /* boundScroll */);
             stackLayout.getStackTransform(event.task, stackScroller.getStackScroll(), tmpTransform,
                     null);
-            tmpTransform.scale = event.taskView.getScaleX();
-            tmpTransform.rect.offset(event.taskView.getTranslationX(),
-                    event.taskView.getTranslationY());
+            tmpTransform.alpha = 0;
+            tmpTransform.scale = 1f;
+            tmpTransform.rect.set(taskViewRect);
             mTaskStackView.updateTaskViewToTransform(event.taskView, tmpTransform,
-                    new TaskViewAnimation(150, mFastOutLinearInInterpolator,
+                    new TaskViewAnimation(125, PhoneStatusBar.ALPHA_OUT,
                             new AnimatorListenerAdapter() {
                                 @Override
                                 public void onAnimationEnd(Animator animation) {
+                                    // Dock the task and launch it
+                                    SystemServicesProxy ssp = Recents.getSystemServices();
+                                    ssp.startTaskInDockedMode(getContext(), event.taskView,
+                                            event.task.key.id, dockState.createMode);
+
                                     mTaskStackView.getStack().removeTask(event.task);
                                 }
                             }));
 
-            // Dock the task and launch it
-            SystemServicesProxy ssp = Recents.getSystemServices();
-            ssp.startTaskInDockedMode(event.task.key.id, dockState.createMode);
-            launchTask(event.task, null, INVALID_STACK_ID);
 
             MetricsLogger.action(mContext,
                     MetricsLogger.ACTION_WINDOW_DOCK_DRAG_DROP);
+        } else {
+            // Animate the overlay alpha back to 0
+            updateVisibleDockRegions(null, true /* isDefaultDockState */, -1,
+                    true /* animateAlpha */, false /* animateBounds */);
         }
     }
 
@@ -638,23 +662,32 @@
     /**
      * Updates the dock region to match the specified dock state.
      */
-    private void updateVisibleDockRegions(TaskStack.DockState[] newDockStates, int overrideAlpha) {
-        ArraySet<TaskStack.DockState> newDockStatesSet = new ArraySet<>();
-        if (newDockStates != null) {
-            Collections.addAll(newDockStatesSet, newDockStates);
-        }
-        for (TaskStack.DockState dockState : mVisibleDockStates) {
+    private void updateVisibleDockRegions(TaskStack.DockState[] newDockStates,
+            boolean isDefaultDockState, int overrideAlpha, boolean animateAlpha,
+            boolean animateBounds) {
+        ArraySet<TaskStack.DockState> newDockStatesSet = Utilities.arrayToSet(newDockStates,
+                new ArraySet<TaskStack.DockState>());
+        ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
+        for (int i = visDockStates.size() - 1; i >= 0; i--) {
+            TaskStack.DockState dockState = visDockStates.get(i);
             TaskStack.DockState.ViewState viewState = dockState.viewState;
             if (newDockStates == null || !newDockStatesSet.contains(dockState)) {
                 // This is no longer visible, so hide it
-                viewState.startAlphaAnimation(0, 150);
+                viewState.startAnimation(null, 0, DOCK_AREA_OVERLAY_TRANSITION_DURATION,
+                        PhoneStatusBar.ALPHA_OUT, animateAlpha, animateBounds);
             } else {
                 // This state is now visible, update the bounds and show it
                 int alpha = (overrideAlpha != -1 ? overrideAlpha : viewState.dockAreaAlpha);
-                viewState.dockAreaOverlay.setBounds(
-                        dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight()));
-                viewState.dockAreaOverlay.setCallback(this);
-                viewState.startAlphaAnimation(alpha, 150);
+                Rect bounds = isDefaultDockState
+                        ? dockState.getPreDockedBounds(getMeasuredWidth(), getMeasuredHeight())
+                        : dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight(),
+                        mDividerSize, mSystemInsets, getResources());
+                if (viewState.dockAreaOverlay.getCallback() != this) {
+                    viewState.dockAreaOverlay.setCallback(this);
+                    viewState.dockAreaOverlay.setBounds(bounds);
+                }
+                viewState.startAnimation(bounds, alpha, DOCK_AREA_OVERLAY_TRANSITION_DURATION,
+                        PhoneStatusBar.ALPHA_IN, animateAlpha, animateBounds);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 473334b..d8698ee 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -19,6 +19,7 @@
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.view.MotionEvent;
+import android.view.ViewConfiguration;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.events.EventBus;
@@ -64,13 +65,17 @@
 
     private Point mTaskViewOffset = new Point();
     private Point mDownPos = new Point();
-    private boolean mDragging;
+    private boolean mDragRequested;
+    private boolean mIsDragging;
+    private float mDragSlop;
 
     private DropTarget mLastDropTarget;
     private ArrayList<DropTarget> mDropTargets = new ArrayList<>();
+    private ArrayList<TaskStack.DockState> mVisibleDockStates = new ArrayList<>();
 
     public RecentsViewTouchHandler(RecentsView rv) {
         mRv = rv;
+        mDragSlop = ViewConfiguration.get(rv.getContext()).getScaledTouchSlop();
     }
 
     /**
@@ -93,16 +98,23 @@
         return dockStates;
     }
 
+    /**
+     * Returns the set of visible dock states for this current drag.
+     */
+    public ArrayList<TaskStack.DockState> getVisibleDockStates() {
+        return mVisibleDockStates;
+    }
+
     /** Touch preprocessing for handling below */
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         handleTouchEvent(ev);
-        return mDragging;
+        return mDragRequested;
     }
 
     /** Handles touch events once we have intercepted them */
     public boolean onTouchEvent(MotionEvent ev) {
         handleTouchEvent(ev);
-        return mDragging;
+        return mDragRequested;
     }
 
     /**** Events ****/
@@ -110,7 +122,9 @@
     public final void onBusEvent(DragStartEvent event) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         mRv.getParent().requestDisallowInterceptTouchEvent(true);
-        mDragging = true;
+        mDragRequested = true;
+        // We defer starting the actual drag handling until the user moves past the drag slop
+        mIsDragging = false;
         mDragTask = event.task;
         mTaskView = event.taskView;
         mDropTargets.clear();
@@ -124,11 +138,13 @@
         mTaskView.setTranslationX(x);
         mTaskView.setTranslationY(y);
 
-        if (!ssp.hasDockedTask()) {
+        mVisibleDockStates.clear();
+        if (!ssp.hasDockedTask() && mRv.getTaskStack().getTaskCount() > 1) {
             // Add the dock state drop targets (these take priority)
             TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation();
             for (TaskStack.DockState dockState : dockStates) {
                 registerDropTargetForCurrentDrag(dockState);
+                mVisibleDockStates.add(dockState);
             }
         }
 
@@ -137,7 +153,7 @@
     }
 
     public final void onBusEvent(DragEndEvent event) {
-        mDragging = false;
+        mDragRequested = false;
         mDragTask = null;
         mTaskView = null;
         mLastDropTarget = null;
@@ -153,25 +169,45 @@
                 mDownPos.set((int) ev.getX(), (int) ev.getY());
                 break;
             case MotionEvent.ACTION_MOVE: {
-                if (mDragging) {
-                    int width = mRv.getMeasuredWidth();
-                    int height = mRv.getMeasuredHeight();
-                    float evX = ev.getX();
-                    float evY = ev.getY();
-                    float x = evX - mTaskViewOffset.x;
-                    float y = evY - mTaskViewOffset.y;
+                float evX = ev.getX();
+                float evY = ev.getY();
+                float x = evX - mTaskViewOffset.x;
+                float y = evY - mTaskViewOffset.y;
 
-                    DropTarget currentDropTarget = null;
-                    for (DropTarget target : mDropTargets) {
-                        if (target.acceptsDrop((int) evX, (int) evY, width, height)) {
-                            currentDropTarget = target;
-                            break;
-                        }
+                if (mDragRequested) {
+                    if (!mIsDragging) {
+                        mIsDragging = Math.hypot(evX - mDownPos.x, evY - mDownPos.y) > mDragSlop;
                     }
-                    if (mLastDropTarget != currentDropTarget) {
-                        mLastDropTarget = currentDropTarget;
-                        EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask,
-                                currentDropTarget));
+                    if (mIsDragging) {
+                        int width = mRv.getMeasuredWidth();
+                        int height = mRv.getMeasuredHeight();
+
+                        DropTarget currentDropTarget = null;
+
+                        // Give priority to the current drop target to retain the touch handling
+                        if (mLastDropTarget != null) {
+                            if (mLastDropTarget.acceptsDrop((int) evX, (int) evY, width, height,
+                                    true /* isCurrentTarget */)) {
+                                currentDropTarget = mLastDropTarget;
+                            }
+                        }
+
+                        // Otherwise, find the next target to handle this event
+                        if (currentDropTarget == null) {
+                            for (DropTarget target : mDropTargets) {
+                                if (target.acceptsDrop((int) evX, (int) evY, width, height,
+                                        false /* isCurrentTarget */)) {
+                                    currentDropTarget = target;
+                                    break;
+                                }
+                            }
+                        }
+                        if (mLastDropTarget != currentDropTarget) {
+                            mLastDropTarget = currentDropTarget;
+                            EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask,
+                                    currentDropTarget));
+                        }
+
                     }
 
                     mTaskView.setTranslationX(x);
@@ -181,7 +217,7 @@
             }
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL: {
-                if (mDragging) {
+                if (mDragRequested) {
                     EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView,
                             mLastDropTarget));
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
deleted file mode 100644
index b7c1de3..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.util.DisplayMetrics;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-
-/**
- * This class facilitates swipe to dismiss. It defines an interface to be implemented by the
- * by the class hosting the views that need to swiped, and, using this interface, handles touch
- * events and translates / fades / animates the view as it is dismissed.
- */
-public class SwipeHelper {
-    static final String TAG = "SwipeHelper";
-    private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
-    private static final boolean CONSTRAIN_SWIPE = true;
-    private static final boolean FADE_OUT_DURING_SWIPE = true;
-    private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true;
-
-    public static final int X = 0;
-    public static final int Y = 1;
-
-    private static LinearInterpolator sLinearInterpolator = new LinearInterpolator();
-    private Interpolator mLinearOutSlowInInterpolator;
-
-    private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
-    private int DEFAULT_ESCAPE_ANIMATION_DURATION = 75; // ms
-    private int MAX_ESCAPE_ANIMATION_DURATION = 150; // ms
-    private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 250; // ms
-
-    public static float ALPHA_FADE_START = 0.15f; // fraction of thumbnail width
-                                                 // where fade starts
-    static final float ALPHA_FADE_END = 0.65f; // fraction of thumbnail width
-                                              // beyond which alpha->0
-    private float mMinAlpha = 0f;
-
-    private float mPagingTouchSlop;
-    Callback mCallback;
-    private int mSwipeDirection;
-    private VelocityTracker mVelocityTracker;
-
-    private float mInitialTouchPos;
-    private boolean mDragging;
-    private float mSnapBackTranslationX;
-
-    private View mCurrView;
-    private boolean mCanCurrViewBeDimissed;
-    private float mDensityScale;
-
-    public boolean mAllowSwipeTowardsStart = true;
-    public boolean mAllowSwipeTowardsEnd = true;
-    private boolean mRtl;
-
-    public SwipeHelper(Context context, int swipeDirection, Callback callback, float densityScale,
-            float pagingTouchSlop) {
-        mCallback = callback;
-        mSwipeDirection = swipeDirection;
-        mVelocityTracker = VelocityTracker.obtain();
-        mDensityScale = densityScale;
-        mPagingTouchSlop = pagingTouchSlop;
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
-                com.android.internal.R.interpolator.linear_out_slow_in);
-    }
-
-    public void setDensityScale(float densityScale) {
-        mDensityScale = densityScale;
-    }
-
-    public void setSnapBackTranslationX(float translationX) {
-        mSnapBackTranslationX = translationX;
-    }
-
-    public void setPagingTouchSlop(float pagingTouchSlop) {
-        mPagingTouchSlop = pagingTouchSlop;
-    }
-
-    public void cancelOngoingDrag() {
-        if (mDragging) {
-            if (mCurrView != null) {
-                mCallback.onDragCancelled(mCurrView);
-                setTranslation(mCurrView, 0);
-                mCallback.onSnapBackCompleted(mCurrView);
-                mCurrView = null;
-            }
-            mDragging = false;
-        }
-    }
-
-    public void resetTranslation(View v) {
-        setTranslation(v, 0);
-    }
-
-    private float getPos(MotionEvent ev) {
-        return mSwipeDirection == X ? ev.getX() : ev.getY();
-    }
-
-    private float getTranslation(View v) {
-        return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY();
-    }
-
-    private float getVelocity(VelocityTracker vt) {
-        return mSwipeDirection == X ? vt.getXVelocity() :
-                vt.getYVelocity();
-    }
-
-    private ObjectAnimator createTranslationAnimation(View v, float newPos) {
-        ObjectAnimator anim = ObjectAnimator.ofFloat(v,
-                mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
-        return anim;
-    }
-
-    private float getPerpendicularVelocity(VelocityTracker vt) {
-        return mSwipeDirection == X ? vt.getYVelocity() :
-                vt.getXVelocity();
-    }
-
-    private void setTranslation(View v, float translate) {
-        if (mSwipeDirection == X) {
-            v.setTranslationX(translate);
-        } else {
-            v.setTranslationY(translate);
-        }
-    }
-
-    private float getSize(View v) {
-        final DisplayMetrics dm = v.getContext().getResources().getDisplayMetrics();
-        return mSwipeDirection == X ? dm.widthPixels : dm.heightPixels;
-    }
-
-    public void setMinAlpha(float minAlpha) {
-        mMinAlpha = minAlpha;
-    }
-
-    float getAlphaForOffset(View view) {
-        float viewSize = getSize(view);
-        final float fadeSize = ALPHA_FADE_END * viewSize;
-        float result = 1.0f;
-        float pos = getTranslation(view);
-        if (pos >= viewSize * ALPHA_FADE_START) {
-            result = 1.0f - (pos - viewSize * ALPHA_FADE_START) / fadeSize;
-        } else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) {
-            result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize;
-        }
-        result = Math.min(result, 1.0f);
-        result = Math.max(result, 0f);
-        return Math.max(mMinAlpha, result);
-    }
-
-    /**
-     * Determines whether the given view has RTL layout.
-     */
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-    public static boolean isLayoutRtl(View view) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            return View.LAYOUT_DIRECTION_RTL == view.getLayoutDirection();
-        } else {
-            return false;
-        }
-    }
-
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        final int action = ev.getAction();
-
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mDragging = false;
-                mCurrView = mCallback.getChildAtPosition(ev);
-                mVelocityTracker.clear();
-                if (mCurrView != null) {
-                    mRtl = isLayoutRtl(mCurrView);
-                    mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
-                    mVelocityTracker.addMovement(ev);
-                    mInitialTouchPos = getPos(ev);
-                } else {
-                    mCanCurrViewBeDimissed = false;
-                }
-                break;
-            case MotionEvent.ACTION_MOVE:
-                if (mCurrView != null) {
-                    mVelocityTracker.addMovement(ev);
-                    float pos = getPos(ev);
-                    float delta = pos - mInitialTouchPos;
-                    if (Math.abs(delta) > mPagingTouchSlop) {
-                        mCallback.onBeginDrag(mCurrView);
-                        mDragging = true;
-                        mInitialTouchPos = pos - getTranslation(mCurrView);
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                mDragging = false;
-                mCurrView = null;
-                break;
-        }
-        return mDragging;
-    }
-
-    /**
-     * @param view The view to be dismissed
-     * @param velocity The desired pixels/second speed at which the view should move
-     */
-    private void dismissChild(final View view, float velocity) {
-        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
-        float newPos;
-        if (velocity < 0
-                || (velocity == 0 && getTranslation(view) < 0)
-                // if we use the Menu to dismiss an item in landscape, animate up
-                || (velocity == 0 && getTranslation(view) == 0 && mSwipeDirection == Y)) {
-            newPos = -getSize(view);
-        } else {
-            newPos = getSize(view);
-        }
-        int duration = MAX_ESCAPE_ANIMATION_DURATION;
-        if (velocity != 0) {
-            duration = Math.min(duration,
-                                (int) (Math.abs(newPos - getTranslation(view)) *
-                                        1000f / Math.abs(velocity)));
-        } else {
-            duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
-        }
-
-        ValueAnimator anim = createTranslationAnimation(view, newPos);
-        anim.setInterpolator(sLinearInterpolator);
-        anim.setDuration(duration);
-        anim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mCallback.onChildDismissed(view);
-                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
-                    view.setAlpha(1.f);
-                }
-            }
-        });
-        anim.addUpdateListener(new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
-                    view.setAlpha(getAlphaForOffset(view));
-                }
-            }
-        });
-        anim.start();
-    }
-
-    private void snapChild(final View view, float velocity) {
-        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
-        ValueAnimator anim = createTranslationAnimation(view, mSnapBackTranslationX);
-        int duration = SNAP_ANIM_LEN;
-        anim.setDuration(duration);
-        anim.setInterpolator(mLinearOutSlowInInterpolator);
-        anim.addUpdateListener(new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
-                    view.setAlpha(getAlphaForOffset(view));
-                }
-                mCallback.onSwipeChanged(mCurrView, view.getTranslationX());
-            }
-        });
-        anim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
-                    view.setAlpha(1.0f);
-                }
-                mCallback.onSnapBackCompleted(view);
-            }
-        });
-        anim.start();
-    }
-
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (!mDragging) {
-            if (!onInterceptTouchEvent(ev)) {
-                return mCanCurrViewBeDimissed;
-            }
-        }
-
-        mVelocityTracker.addMovement(ev);
-        final int action = ev.getAction();
-        switch (action) {
-            case MotionEvent.ACTION_OUTSIDE:
-            case MotionEvent.ACTION_MOVE:
-                if (mCurrView != null) {
-                    float delta = getPos(ev) - mInitialTouchPos;
-                    setSwipeAmount(delta);
-                    mCallback.onSwipeChanged(mCurrView, delta);
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                if (mCurrView != null) {
-                    endSwipe(mVelocityTracker);
-                }
-                break;
-        }
-        return true;
-    }
-
-    private void setSwipeAmount(float amount) {
-        // don't let items that can't be dismissed be dragged more than
-        // maxScrollDistance
-        if (CONSTRAIN_SWIPE
-                && (!isValidSwipeDirection(amount) || !mCallback.canChildBeDismissed(mCurrView))) {
-            float size = getSize(mCurrView);
-            float maxScrollDistance = 0.15f * size;
-            if (Math.abs(amount) >= size) {
-                amount = amount > 0 ? maxScrollDistance : -maxScrollDistance;
-            } else {
-                amount = maxScrollDistance * (float) Math.sin((amount/size)*(Math.PI/2));
-            }
-        }
-        setTranslation(mCurrView, amount);
-        if (FADE_OUT_DURING_SWIPE && mCanCurrViewBeDimissed) {
-            float alpha = getAlphaForOffset(mCurrView);
-            mCurrView.setAlpha(alpha);
-        }
-    }
-
-    private boolean isValidSwipeDirection(float amount) {
-        if (mSwipeDirection == X) {
-            if (mRtl) {
-                return (amount <= 0) ? mAllowSwipeTowardsEnd : mAllowSwipeTowardsStart;
-            } else {
-                return (amount <= 0) ? mAllowSwipeTowardsStart : mAllowSwipeTowardsEnd;
-            }
-        }
-
-        // Vertical swipes are always valid.
-        return true;
-    }
-
-    private void endSwipe(VelocityTracker velocityTracker) {
-        velocityTracker.computeCurrentVelocity(1000 /* px/sec */);
-        float velocity = getVelocity(velocityTracker);
-        float perpendicularVelocity = getPerpendicularVelocity(velocityTracker);
-        float escapeVelocity = SWIPE_ESCAPE_VELOCITY * mDensityScale;
-        float translation = getTranslation(mCurrView);
-        // Decide whether to dismiss the current view
-        boolean childSwipedFarEnough = DISMISS_IF_SWIPED_FAR_ENOUGH &&
-                Math.abs(translation) > 0.6 * getSize(mCurrView);
-        boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) &&
-                (Math.abs(velocity) > Math.abs(perpendicularVelocity)) &&
-                (velocity > 0) == (translation > 0);
-
-        boolean dismissChild = mCallback.canChildBeDismissed(mCurrView)
-                && isValidSwipeDirection(translation)
-                && (childSwipedFastEnough || childSwipedFarEnough);
-
-        if (dismissChild) {
-            // flingadingy
-            dismissChild(mCurrView, childSwipedFastEnough ? velocity : 0f);
-        } else {
-            // snappity
-            mCallback.onDragCancelled(mCurrView);
-            snapChild(mCurrView, velocity);
-        }
-    }
-
-    public interface Callback {
-        View getChildAtPosition(MotionEvent ev);
-
-        boolean canChildBeDismissed(View v);
-
-        void onBeginDrag(View v);
-
-        void onSwipeChanged(View v, float delta);
-
-        void onChildDismissed(View v);
-
-        void onSnapBackCompleted(View v);
-
-        void onDragCancelled(View v);
-    }
-}
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 80a35de..2930f4d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -97,7 +97,7 @@
         Task launchTargetTask = stack.getLaunchTarget();
 
         // Break early if there are no tasks
-        if (stack.getStackTaskCount() == 0) {
+        if (stack.getTaskCount() == 0) {
             return;
         }
 
@@ -159,7 +159,7 @@
         Task launchTargetTask = stack.getLaunchTarget();
 
         // Break early if there are no tasks
-        if (stack.getStackTaskCount() == 0) {
+        if (stack.getTaskCount() == 0) {
             return;
         }
 
@@ -229,7 +229,7 @@
         TaskStack stack = mStackView.getStack();
 
         // Break early if there are no tasks
-        if (stack.getStackTaskCount() == 0) {
+        if (stack.getTaskCount() == 0) {
             return;
         }
 
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 c2bb745..68ff63c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -21,6 +21,8 @@
 import android.content.res.Resources;
 import android.graphics.Path;
 import android.graphics.Rect;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.FloatProperty;
 import android.util.Property;
 import android.view.animation.AnimationUtils;
@@ -37,7 +39,6 @@
 import com.android.systemui.recents.model.TaskStack;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 
 /**
  * Used to describe a visible range that can be normalized to [0, 1].
@@ -137,9 +138,8 @@
         public static StackState getStackStateForStack(TaskStack stack) {
             SystemServicesProxy ssp = Recents.getSystemServices();
             boolean hasFreeformWorkspaces = ssp.hasFreeformWorkspaceSupport();
-            int taskCount = stack.getStackTaskCount();
-            int freeformCount = stack.getStackTaskFreeformCount();
-            int stackCount = taskCount - freeformCount;
+            int freeformCount = stack.getFreeformTaskCount();
+            int stackCount = stack.getStackTaskCount();
             if (hasFreeformWorkspaces && stackCount > 0 && freeformCount > 0) {
                 return SPLIT;
             } else if (hasFreeformWorkspaces && freeformCount > 0) {
@@ -270,7 +270,7 @@
     int mMaxTranslationZ;
 
     // Optimization, allows for quick lookup of task -> index
-    private HashMap<Task.TaskKey, Integer> mTaskIndexMap = new HashMap<>();
+    private ArrayMap<Task.TaskKey, Integer> mTaskIndexMap = new ArrayMap<>();
 
     // The freeform workspace layout
     FreeformWorkspaceLayoutAlgorithm mFreeformLayoutAlgorithm;
@@ -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) {
+    void update(TaskStack stack, ArraySet<Task> ignoreTasksSet) {
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Clear the progress map
@@ -393,6 +393,9 @@
         ArrayList<Task> stackTasks = new ArrayList<>();
         for (int i = 0; i < tasks.size(); i++) {
             Task task = tasks.get(i);
+            if (ignoreTasksSet.contains(task)) {
+                continue;
+            }
             if (task.isFreeformTask()) {
                 freeformTasks.add(task);
             } else {
@@ -645,7 +648,11 @@
             y += (mStackRect.top - mTaskRect.top);
             z = Math.max(mMinTranslationZ, Math.min(mMaxTranslationZ,
                     mMinTranslationZ + (p * (mMaxTranslationZ - mMinTranslationZ))));
-            relP = unfocusedP;
+            if (mNumStackTasks == 1) {
+                relP = 1f;
+            } else {
+                relP = Math.min(mMaxScrollP, unfocusedP);
+            }
         }
 
         // Fill out the transform
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 9568fac..7583a19 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -28,8 +28,8 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.provider.Settings;
-import android.util.IntProperty;
-import android.util.Property;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -77,8 +77,7 @@
 import com.android.systemui.recents.model.TaskStack;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.Collections;
 import java.util.List;
 
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
@@ -105,19 +104,6 @@
     private static final int DRAG_SCALE_DURATION = 175;
     private static final float DRAG_SCALE_FACTOR = 1.05f;
 
-    public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
-            new IntProperty<Drawable>("drawableAlpha") {
-                @Override
-                public void setValue(Drawable object, int alpha) {
-                    object.setAlpha(alpha);
-                }
-
-                @Override
-                public Integer get(Drawable object) {
-                    return object.getAlpha();
-                }
-            };
-
     TaskStack mStack;
     TaskStackLayoutAlgorithm mLayoutAlgorithm;
     TaskStackViewScroller mStackScroller;
@@ -126,6 +112,7 @@
     GradientDrawable mFreeformWorkspaceBackground;
     ObjectAnimator mFreeformWorkspaceBackgroundAnimator;
     ViewPool<TaskView, Task> mViewPool;
+    boolean mStartTimerIndicator;
 
     ArrayList<TaskView> mTaskViews = new ArrayList<>();
     ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
@@ -135,6 +122,7 @@
     Task mFocusedTask;
 
     int mTaskCornerRadiusPx;
+    private int mDividerSize;
 
     boolean mTaskViewsClipDirty = true;
     boolean mAwaitingFirstLayout = true;
@@ -142,10 +130,14 @@
     boolean mTouchExplorationEnabled;
     boolean mScreenPinningEnabled;
 
-    Rect mTaskStackBounds = new Rect();
+    // The stable stack bounds are the full bounds that we were measured with from RecentsView
+    Rect mStableStackBounds = new Rect();
+    // The current stack bounds are dynamic and may change as the user drags and drops
+    Rect mStackBounds = new Rect();
     int[] mTmpVisibleRange = new int[2];
     Rect mTmpRect = new Rect();
-    HashMap<Task, TaskView> mTmpTaskViewMap = new HashMap<>();
+    ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
+    ArraySet<Task> mTmpTaskSet = new ArraySet<>();
     List<TaskView> mTmpTaskViews = new ArrayList<>();
     TaskViewTransform mTmpTransform = new TaskViewTransform();
     LayoutInflater mInflater;
@@ -157,23 +149,35 @@
             new ValueAnimator.AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    mTaskViewsClipDirty = true;
-                    invalidate();
+                    if (!mTaskViewsClipDirty) {
+                        mTaskViewsClipDirty = true;
+                        invalidate();
+                    }
                 }
             };
 
     // The drop targets for a task drag
     private DropTarget mFreeformWorkspaceDropTarget = new DropTarget() {
         @Override
-        public boolean acceptsDrop(int x, int y, int width, int height) {
-            return mLayoutAlgorithm.mFreeformRect.contains(x, y);
+        public boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget) {
+            // This drop target has a fixed bounds and should be checked last, so just fall through
+            // if it is the current target
+            if (!isCurrentTarget) {
+                return mLayoutAlgorithm.mFreeformRect.contains(x, y);
+            }
+            return false;
         }
     };
 
     private DropTarget mStackDropTarget = new DropTarget() {
         @Override
-        public boolean acceptsDrop(int x, int y, int width, int height) {
-            return mLayoutAlgorithm.mStackRect.contains(x, y);
+        public boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget) {
+            // This drop target has a fixed bounds and should be checked last, so just fall through
+            // if it is the current target
+            if (!isCurrentTarget) {
+                return mLayoutAlgorithm.mStackRect.contains(x, y);
+            }
+            return false;
         }
     };
 
@@ -195,6 +199,7 @@
                 com.android.internal.R.interpolator.fast_out_slow_in);
         mTaskCornerRadiusPx = res.getDimensionPixelSize(
                 R.dimen.recents_task_view_rounded_corners_radius);
+        mDividerSize = ssp.getDockedDividerSize(context);
 
         int taskBarDismissDozeDelaySeconds = getResources().getInteger(
                 R.integer.recents_task_bar_dismiss_delay_seconds);
@@ -223,11 +228,8 @@
 
     @Override
     protected void onAttachedToWindow() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
-        mScreenPinningEnabled = ssp.getSystemSetting(getContext(),
-                Settings.System.LOCK_TO_APP_ENABLED) != 0;
         EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
+        readSystemFlags();
         super.onAttachedToWindow();
     }
 
@@ -333,6 +335,7 @@
         mUIDozeTrigger.resetTrigger();
         mStackScroller.reset();
         mLayoutAlgorithm.reset();
+        readSystemFlags();
         requestLayout();
     }
 
@@ -346,29 +349,24 @@
      * This call ignores freeform tasks.
      */
     private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
-                                       ArrayList<Task> tasks,
-                                       float stackScroll,
-                                       int[] visibleRangeOut) {
+            ArrayList<Task> tasks, float stackScroll,
+            int[] visibleRangeOut, ArraySet<Task> ignoreTasksSet) {
         int taskTransformCount = taskTransforms.size();
         int taskCount = tasks.size();
         int frontMostVisibleIndex = -1;
         int backMostVisibleIndex = -1;
 
         // We can reuse the task transforms where possible to reduce object allocation
-        if (taskTransformCount < taskCount) {
-            // If there are less transforms than tasks, then add as many transforms as necessary
-            for (int i = taskTransformCount; i < taskCount; i++) {
-                taskTransforms.add(new TaskViewTransform());
-            }
-        } else if (taskTransformCount > taskCount) {
-            // If there are more transforms than tasks, then just subset the transform list
-            taskTransforms.subList(0, taskCount);
-        }
+        Utilities.matchTaskListSize(tasks, taskTransforms);
 
         // Update the stack transforms
         TaskViewTransform frontTransform = null;
         for (int i = taskCount - 1; i >= 0; i--) {
             Task task = tasks.get(i);
+            if (ignoreTasksSet.contains(task)) {
+                continue;
+            }
+
             TaskViewTransform transform = mLayoutAlgorithm.getStackTransform(task, stackScroll,
                     taskTransforms.get(i), frontTransform);
 
@@ -409,28 +407,34 @@
      * they are initially picked up from the pool, when they will be placed in a suitable initial
      * position.
      */
-    private void bindTaskViewsWithStack() {
+    private void bindTaskViewsWithStack(ArraySet<Task> ignoreTasksSet) {
         final float stackScroll = mStackScroller.getStackScroll();
         final int[] visibleStackRange = mTmpVisibleRange;
 
         // Get all the task transforms
         final ArrayList<Task> tasks = mStack.getStackTasks();
-        final boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
-                stackScroll, visibleStackRange);
+        final boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms,
+                tasks, stackScroll, visibleStackRange, ignoreTasksSet);
 
         // Return all the invisible children to the pool
-        mTmpTaskViewMap.clear();
         final List<TaskView> taskViews = getTaskViews();
         final int taskViewCount = taskViews.size();
         int lastFocusedTaskIndex = -1;
+        mTmpTaskViewMap.clear();
+        mTmpTaskViewMap.ensureCapacity(tasks.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);
 
+            // Skip ignored tasks
+            if (ignoreTasksSet.contains(task)) {
+                continue;
+            }
+
             if (task.isFreeformTask() ||
                     visibleStackRange[1] <= taskIndex && taskIndex <= visibleStackRange[0]) {
-                mTmpTaskViewMap.put(task, tv);
+                mTmpTaskViewMap.put(task.key, tv);
             } else {
                 if (mTouchExplorationEnabled) {
                     lastFocusedTaskIndex = taskIndex;
@@ -442,16 +446,21 @@
 
         // Pick up all the newly visible children
         int lastVisStackIndex = isValidVisibleStackRange ? visibleStackRange[1] : 0;
-        for (int i = mStack.getStackTaskCount() - 1; i >= lastVisStackIndex; i--) {
+        for (int i = mStack.getTaskCount() - 1; i >= lastVisStackIndex; i--) {
             final Task task = tasks.get(i);
             final TaskViewTransform transform = mCurrentTaskTransforms.get(i);
 
+            // Skip ignored tasks
+            if (ignoreTasksSet.contains(task)) {
+                continue;
+            }
+
             // Skip the invisible non-freeform stack tasks
             if (i > visibleStackRange[0] && !task.isFreeformTask()) {
                 continue;
             }
 
-            TaskView tv = mTmpTaskViewMap.get(task);
+            TaskView tv = mTmpTaskViewMap.get(task.key);
             if (tv == null) {
                 tv = mViewPool.pickUpViewFromPool(task, task);
                 if (task.isFreeformTask()) {
@@ -495,8 +504,16 @@
     /**
      * Cancels any existing {@link TaskView} animations, and updates each {@link TaskView} to its
      * current position as defined by the {@link TaskStackLayoutAlgorithm}.
+     *
+     * @param ignoreTasks the set of tasks to ignore in the relayout
      */
-    private void updateTaskViewsToLayout(TaskViewAnimation animation) {
+    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);
+
         // If we had a deferred animation, cancel that
         mDeferredTaskViewUpdateAnimation = null;
 
@@ -504,7 +521,7 @@
         cancelAllTaskViewAnimations();
 
         // Fetch the current set of TaskViews
-        bindTaskViewsWithStack();
+        bindTaskViewsWithStack(ignoreTasksSet);
 
         // Animate them to their final transforms with the given animation
         List<TaskView> taskViews = getTaskViews();
@@ -514,6 +531,10 @@
             final int taskIndex = mStack.indexOfStackTask(tv.getTask());
             final TaskViewTransform transform = mCurrentTaskTransforms.get(taskIndex);
 
+            if (ignoreTasksSet.contains(tv.getTask())) {
+                continue;
+            }
+
             updateTaskViewToTransform(tv, transform, animation);
         }
     }
@@ -541,8 +562,7 @@
      */
     private void cancelAllTaskViewAnimations() {
         List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
+        for (int i = taskViews.size() - 1; i >= 0; i--) {
             final TaskView tv = taskViews.get(i);
             tv.cancelTransformAnimation();
         }
@@ -593,10 +613,20 @@
         mTaskViewsClipDirty = false;
     }
 
-    /** Updates the min and max virtual scroll bounds */
-    void updateLayout(boolean boundScrollToNewMinMax) {
+    /**
+     * Updates the min and max virtual scroll bounds.
+     *
+     * @param ignoreTasks 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);
+
         // Compute the min and max scroll values
-        mLayoutAlgorithm.update(mStack);
+        mLayoutAlgorithm.update(mStack, ignoreTasksSet);
 
         // Update the freeform workspace
         SystemServicesProxy ssp = Recents.getSystemServices();
@@ -623,24 +653,55 @@
      */
     private boolean setFocusedTask(int taskIndex, boolean scrollToTask,
             final boolean requestViewFocus) {
+        return setFocusedTask(taskIndex, scrollToTask, requestViewFocus, false);
+    }
+
+    /**
+     * Sets the focused task to the provided (bounded taskIndex).
+     *
+     * @return whether or not the stack will scroll as a part of this focus change
+     */
+    private boolean setFocusedTask(int taskIndex, boolean scrollToTask,
+            final boolean requestViewFocus, final boolean showTimerIndicator) {
         // Find the next task to focus
-        int newFocusedTaskIndex = mStack.getStackTaskCount() > 0 ?
-                Math.max(0, Math.min(mStack.getStackTaskCount() - 1, taskIndex)) : -1;
+        int newFocusedTaskIndex = mStack.getTaskCount() > 0 ?
+                Math.max(0, Math.min(mStack.getTaskCount() - 1, taskIndex)) : -1;
         final Task newFocusedTask = (newFocusedTaskIndex != -1) ?
                 mStack.getStackTasks().get(newFocusedTaskIndex) : null;
 
         // 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);
+                if (tv != null) {
+                    tv.getHeaderView().cancelFocusTimerIndicator();
+                }
+            }
         }
 
         boolean willScroll = false;
+
         mFocusedTask = newFocusedTask;
+
         if (newFocusedTask != null) {
+            // Start the timer indicator, if applicable
+            if (showTimerIndicator) {
+                final TaskView tv = getChildViewForTask(mFocusedTask);
+                if (tv != null) {
+                    tv.getHeaderView().startFocusTimerIndicator();
+                } else {
+                    // The view is null; set a flag for later
+                    mStartTimerIndicator = true;
+                }
+            }
+
             Runnable focusTaskRunnable = new Runnable() {
                 @Override
                 public void run() {
-                    TaskView tv = getChildViewForTask(newFocusedTask);
+                    final TaskView tv = getChildViewForTask(newFocusedTask);
                     if (tv != null) {
                         tv.setFocusedState(true, requestViewFocus);
                     }
@@ -694,10 +755,28 @@
      * @param animated determines whether to actually draw the highlight along with the change in
      *                            focus.
      * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scroll
-     *                               happens
+     *                               happens.
      */
     public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
                                        boolean cancelWindowAnimations) {
+        setRelativeFocusedTask(forward, stackTasksOnly, animated, false, false);
+    }
+
+    /**
+     * Sets the focused task relative to the currently focused task.
+     *
+     * @param forward whether to go to the next task in the stack (along the curve) or the previous
+     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
+     *                       if the currently focused task is not a stack task, will set the focus
+     *                       to the first visible stack task
+     * @param animated determines whether to actually draw the highlight along with the change in
+     *                            focus.
+     * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scroll
+     *                               happens.
+     * @param showTimerIndicator determines whether or not to show an indicator for the task auto-advance.
+     */
+    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
+                                       boolean cancelWindowAnimations, boolean showTimerIndicator) {
         int newIndex = mStack.indexOfStackTask(mFocusedTask);
         if (mFocusedTask != null) {
             if (stackTasksOnly) {
@@ -721,7 +800,7 @@
             } else {
                 // No restrictions, lets just move to the new task (looping forward/backwards if
                 // necessary)
-                int taskCount = mStack.getStackTaskCount();
+                int taskCount = mStack.getTaskCount();
                 newIndex = (newIndex + (forward ? -1 : 1) + taskCount) % taskCount;
             }
         } else {
@@ -733,7 +812,7 @@
         }
         if (newIndex != -1) {
             boolean willScroll = setFocusedTask(newIndex, true /* scrollToTask */,
-                    true /* requestViewFocus */);
+                    true /* requestViewFocus */, showTimerIndicator);
             if (willScroll && cancelWindowAnimations) {
                 // As we iterate to the next/previous task, cancel any current/lagging window
                 // transition animations
@@ -774,7 +853,7 @@
             event.setToIndex(mStack.indexOfStackTask(frontMostTask.getTask()));
             event.setContentDescription(frontMostTask.getTask().title);
         }
-        event.setItemCount(mStack.getStackTaskCount());
+        event.setItemCount(mStack.getTaskCount());
         event.setScrollY(mStackScroller.mScroller.getCurrY());
         event.setMaxScrollY(mStackScroller.progressToScrollRange(mLayoutAlgorithm.mMaxScrollP));
     }
@@ -790,7 +869,7 @@
             if (focusedTaskIndex > 0) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
             }
-            if (focusedTaskIndex < mStack.getStackTaskCount() - 1) {
+            if (focusedTaskIndex < mStack.getTaskCount() - 1) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
             }
         }
@@ -868,14 +947,18 @@
         }
     }
 
-    /** Computes the stack and task rects */
-    public void computeRects(Rect taskStackBounds) {
+    /**
+     * 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(false);
+        updateLayout(boundScroll, ignoreTasks);
     }
 
     /**
@@ -895,9 +978,19 @@
         return mLayoutAlgorithm.computeStackVisibilityReport(mStack.getStackTasks());
     }
 
+    /**
+     * Updates the expected task stack bounds for this stack view.
+     */
     public void setTaskStackBounds(Rect taskStackBounds, Rect systemInsets) {
-        mTaskStackBounds.set(taskStackBounds);
+        // We can get spurious measure passes with the old bounds when docking, and since we are
+        // using the current stack bounds during drag and drop, don't overwrite them until we
+        // actually get new bounds
+        if (!taskStackBounds.equals(mStableStackBounds)) {
+            mStableStackBounds.set(taskStackBounds);
+            mStackBounds.set(taskStackBounds);
+        }
         mLayoutAlgorithm.setSystemInsets(systemInsets);
+        requestLayout();
     }
 
     /**
@@ -910,14 +1003,15 @@
         int height = MeasureSpec.getSize(heightMeasureSpec);
 
         // Compute our stack/task rects
-        computeRects(mTaskStackBounds);
+        computeRects(mStackBounds, false);
 
         // 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();
         }
-        bindTaskViewsWithStack();
+        mTmpTaskSet.clear();
+        bindTaskViewsWithStack(mTmpTaskSet);
 
         // Measure each of the TaskViews
         mTmpTaskViews.clear();
@@ -996,7 +1090,7 @@
         // until after the enter-animation
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
-        int focusedTaskIndex = launchState.getInitialFocusTaskIndex(mStack.getStackTaskCount());
+        int focusedTaskIndex = launchState.getInitialFocusTaskIndex(mStack.getTaskCount());
         if (focusedTaskIndex != -1) {
             setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
                     false /* requestViewFocus */);
@@ -1011,14 +1105,9 @@
         }
     }
 
-    public boolean isTransformedTouchPointInView(float x, float y, TaskView tv) {
-        final float[] point = new float[2];
-        point[0] = x;
-        point[1] = y;
-        transformPointToViewLocal(point, tv);
-        x = point[0];
-        y = point[1];
-        return (0 <= x) && (x < tv.getWidth()) && (0 <= y) && (y < tv.getHeight());
+    public boolean isTouchPointInView(float x, float y, TaskView tv) {
+        return (tv.getLeft() <= x && x <= tv.getRight()) &&
+                (tv.getTop() <= y && y <= tv.getBottom());
     }
 
     @Override
@@ -1087,11 +1176,9 @@
 
             // 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 = null;
+            Task anchorTask = mStack.getStackFrontMostTask();
             float prevAnchorTaskScroll = 0;
-            boolean pullStackForward = stack.getStackTaskCount() > 0;
-            if (pullStackForward) {
-                anchorTask = mStack.getStackFrontMostTask();
+            if (anchorTask != null) {
                 prevAnchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask);
             }
 
@@ -1102,7 +1189,7 @@
                 // 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 (pullStackForward) {
+            } else if (anchorTask != null) {
                 // Otherwise, offset the scroll by the movement of the anchor task
                 float anchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask);
                 float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
@@ -1139,11 +1226,8 @@
         }
 
         // If there are no remaining tasks, then just close recents
-        if (mStack.getStackTaskCount() == 0) {
-            boolean shouldFinishActivity = (mStack.getStackTaskCount() == 0);
-            if (shouldFinishActivity) {
-                EventBus.getDefault().send(new AllTaskViewsDismissedEvent());
-            }
+        if (mStack.getTaskCount() == 0) {
+            EventBus.getDefault().send(new AllTaskViewsDismissedEvent());
         }
     }
 
@@ -1210,6 +1294,11 @@
         tv.setClipViewInStack(true);
         if (mFocusedTask == task) {
             tv.setFocusedState(true, false /* requestViewFocus */);
+            if (mStartTimerIndicator) {
+                // The timer indicator couldn't be started before, so start it now
+                tv.getHeaderView().startFocusTimerIndicator();
+                mStartTimerIndicator = false;
+            }
         }
 
         // Restore the action button visibility if it is the front most task view
@@ -1251,7 +1340,7 @@
 
     public final void onBusEvent(PackagesChangedEvent event) {
         // Compute which components need to be removed
-        HashSet<ComponentName> removedComponents = mStack.computeComponentsRemoved(
+        ArraySet<ComponentName> removedComponents = mStack.computeComponentsRemoved(
                 event.packageName, event.userId);
 
         // For other tasks, just remove them directly if they no longer exist
@@ -1318,7 +1407,8 @@
     }
 
     public final void onBusEvent(FocusNextTaskViewEvent event) {
-        setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */);
+        setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */, false,
+                event.showTimerIndicator);
     }
 
     public final void onBusEvent(FocusPreviousTaskViewEvent event) {
@@ -1328,6 +1418,9 @@
     public final void onBusEvent(UserInteractionEvent event) {
         // Poke the doze trigger on user interaction
         mUIDozeTrigger.poke();
+        if (event.showTimerIndicator && mFocusedTask != null) {
+            getChildViewForTask(mFocusedTask).getHeaderView().cancelFocusTimerIndicator();
+        }
     }
 
     public final void onBusEvent(RecentsVisibilityChangedEvent event) {
@@ -1348,6 +1441,7 @@
         mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
                 mTmpTransform, null);
         mTmpTransform.scale = finalScale;
+        mTmpTransform.translationZ = mLayoutAlgorithm.mMaxTranslationZ + 1;
         updateTaskViewToTransform(event.taskView, mTmpTransform,
                 new TaskViewAnimation(DRAG_SCALE_DURATION, mFastOutSlowInInterpolator));
     }
@@ -1361,7 +1455,23 @@
     }
 
     public final void onBusEvent(DragDropTargetChangedEvent event) {
-        // TODO: Animate the freeform workspace background etc.
+        if (event.dropTarget instanceof TaskStack.DockState) {
+            // Calculate the new task stack bounds that matches the window size that Recents will
+            // have after the drop
+            final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
+            mStackBounds.set(dockState.getDockedTaskStackBounds(getMeasuredWidth(),
+                    getMeasuredHeight(), mDividerSize, mLayoutAlgorithm.mSystemInsets,
+                    getResources()));
+            computeRects(mStackBounds, true /* boundScroll */, event.task /* ignoreTask */);
+            updateTaskViewsToLayout(new TaskViewAnimation(250, mFastOutSlowInInterpolator),
+                    event.task /* ignoreTask */);
+        } else {
+            // Restore the pre-drag task stack bounds
+            mStackBounds.set(mStableStackBounds);
+            computeRects(mStackBounds, true /* boundScroll */);
+            updateTaskViewsToLayout(new TaskViewAnimation(250, mFastOutSlowInInterpolator),
+                    event.task /* ignoreTask */);
+        }
     }
 
     public final void onBusEvent(final DragEndEvent event) {
@@ -1420,7 +1530,7 @@
     }
 
     public final void onBusEvent(StackViewScrolledEvent event) {
-        mLayoutAlgorithm.updateFocusStateOnScroll(event.yMovement);
+        mLayoutAlgorithm.updateFocusStateOnScroll(event.yMovement.value);
     }
 
     public final void onBusEvent(IterateRecentsEvent event) {
@@ -1433,7 +1543,7 @@
     public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
         mEnterAnimationComplete = true;
 
-        if (mStack.getStackTaskCount() > 0) {
+        if (mStack.getTaskCount() > 0) {
             // Start the task enter animations
             mAnimationHelper.startEnterAnimation(event.getAnimationTrigger());
 
@@ -1505,7 +1615,7 @@
 
         Utilities.cancelAnimationWithoutCallbacks(mFreeformWorkspaceBackgroundAnimator);
         mFreeformWorkspaceBackgroundAnimator = ObjectAnimator.ofInt(mFreeformWorkspaceBackground,
-                DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
+                Utilities.DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
         mFreeformWorkspaceBackgroundAnimator.setDuration(duration);
         mFreeformWorkspaceBackgroundAnimator.setInterpolator(interpolator);
         mFreeformWorkspaceBackgroundAnimator.start();
@@ -1546,4 +1656,14 @@
     private boolean shouldShowHistoryButton() {
         return !mStack.getHistoricalTasks().isEmpty();
     }
+
+    /**
+     * Reads current system flags related to accessibility and screen pinning.
+     */
+    private void readSystemFlags() {
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
+        mScreenPinningEnabled = ssp.getSystemSetting(getContext(),
+                Settings.System.LOCK_TO_APP_ENABLED) != 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 c748efc..4813c19 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.Animator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Resources;
@@ -29,6 +30,7 @@
 import android.view.ViewParent;
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.events.EventBus;
@@ -71,6 +73,7 @@
     // Used to calculate when a tap is outside a task view rectangle.
     final int mWindowTouchSlop;
 
+    private final StackViewScrolledEvent mStackViewScrolledEvent = new StackViewScrolledEvent();
     SwipeHelper mSwipeHelper;
     boolean mInterceptedBySwipeHelper;
 
@@ -79,19 +82,26 @@
         Resources res = context.getResources();
         ViewConfiguration configuration = ViewConfiguration.get(context);
         mContext = context;
+        mSv = sv;
+        mScroller = scroller;
         mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
         mScrollTouchSlop = configuration.getScaledTouchSlop();
         mWindowTouchSlop = configuration.getScaledWindowTouchSlop();
-        mSv = sv;
-        mScroller = scroller;
         mFlingAnimUtils = new FlingAnimationUtils(context, 0.2f);
-
-        float densityScale = res.getDisplayMetrics().density;
         mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_stack_overscroll);
-        mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this, densityScale,
-                configuration.getScaledPagingTouchSlop());
-        mSwipeHelper.setMinAlpha(1f);
+        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) {
+            @Override
+            protected float getSize(View v) {
+                return mSv.getWidth();
+            }
+
+            @Override
+            protected void updateSnapBackAnimation(Animator anim) {
+                anim.setInterpolator(mSv.mFastOutSlowInInterpolator);
+            }
+        };
+        mSwipeHelper.setDisableHardwareLayers(true);
     }
 
     /** Velocity tracker helpers */
@@ -116,7 +126,7 @@
         for (int i = taskViewCount - 1; i >= 0; i--) {
             TaskView tv = taskViews.get(i);
             if (tv.getVisibility() == View.VISIBLE) {
-                if (mSv.isTransformedTouchPointInView(x, y, tv)) {
+                if (mSv.isTouchPointInView(x, y, tv)) {
                     return tv;
                 }
             }
@@ -207,7 +217,8 @@
                     if (DEBUG) {
                         Log.d(TAG, "scroll: " + curScrollP);
                     }
-                    EventBus.getDefault().send(new StackViewScrolledEvent(y - mLastY));
+                    mStackViewScrolledEvent.updateY(y - mLastY);
+                    EventBus.getDefault().send(mStackViewScrolledEvent);
                 }
 
                 mLastY = y;
@@ -343,7 +354,7 @@
     @Override
     public void onBeginDrag(View v) {
         TaskView tv = (TaskView) v;
-        mSwipeHelper.setSnapBackTranslationX(tv.getTranslationX());
+
         // Disable clipping with the stack while we are swiping
         tv.setClipViewInStack(false);
         // Disallow touch events from this task view
@@ -356,8 +367,8 @@
     }
 
     @Override
-    public void onSwipeChanged(View v, float delta) {
-        // Do nothing
+    public boolean updateSwipeProgress(View v, boolean dismissable, float swipeProgress) {
+        return true;
     }
 
     @Override
@@ -375,7 +386,7 @@
     }
 
     @Override
-    public void onSnapBackCompleted(View v) {
+    public void onChildSnappedBack(View v) {
         TaskView tv = (TaskView) v;
         // Re-enable clipping with the stack
         tv.setClipViewInStack(true);
@@ -387,4 +398,20 @@
     public void onDragCancelled(View v) {
         // Do nothing
     }
+
+    @Override
+    public View getChildContentView(View v) {
+        return v;
+    }
+
+    @Override
+    public boolean isAntiFalsingNeeded() {
+        return false;
+    }
+
+    @Override
+    public float getFalsingThresholdFactor() {
+        return 0;
+    }
+
 }
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 bc441b2..9b72702 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -257,18 +257,26 @@
         mTmpAnimators.clear();
         toTransform.applyToTaskView(this, mTmpAnimators, toAnimation, !config.fakeShadows);
         if (toAnimation.isImmediate()) {
-            setTaskProgress(toTransform.p);
+            if (Float.compare(getTaskProgress(), toTransform.p) != 0) {
+                setTaskProgress(toTransform.p);
+            }
+            // Manually call back to the animator listener and update callback
             if (toAnimation.listener != null) {
                 toAnimation.listener.onAnimationEnd(null);
             }
+            if (updateCallback != null) {
+                updateCallback.onAnimationUpdate(null);
+            }
         } else {
             if (Float.compare(getTaskProgress(), toTransform.p) != 0) {
                 mTmpAnimators.add(ObjectAnimator.ofFloat(this, TASK_PROGRESS, getTaskProgress(),
                         toTransform.p));
             }
-            ValueAnimator updateCallbackAnim = ValueAnimator.ofInt(0, 1);
-            updateCallbackAnim.addUpdateListener(updateCallback);
-            mTmpAnimators.add(updateCallbackAnim);
+            if (updateCallback != null) {
+                ValueAnimator updateCallbackAnim = ValueAnimator.ofInt(0, 1);
+                updateCallbackAnim.addUpdateListener(updateCallback);
+                mTmpAnimators.add(updateCallbackAnim);
+            }
 
             // Create the animator
             mTransformAnimation = toAnimation.createAnimator(mTmpAnimators);
@@ -286,7 +294,7 @@
 
         mActionButtonView.setScaleX(1f);
         mActionButtonView.setScaleY(1f);
-        mActionButtonView.setAlpha(1f);
+        mActionButtonView.setAlpha(0f);
         mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
     }
 
@@ -360,6 +368,10 @@
         updateDimFromTaskProgress();
     }
 
+    public TaskViewHeader getHeaderView() {
+        return mHeaderView;
+    }
+
     /** Returns the current task progress. */
     public float getTaskProgress() {
         return mTaskProgress;
@@ -455,7 +467,6 @@
                         .scaleY(1f)
                         .setDuration(fadeInDuration)
                         .setInterpolator(PhoneStatusBar.ALPHA_IN)
-                        .withLayer()
                         .start();
             }
         } else {
@@ -494,7 +505,6 @@
                                 mActionButtonView.setVisibility(View.INVISIBLE);
                             }
                         })
-                        .withLayer()
                         .start();
             }
         } else {
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 6a47424..e7717ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -5,7 +5,7 @@
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -23,17 +23,20 @@
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
+import android.graphics.PorterDuff;
 import android.graphics.PixelFormat;
 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.util.AttributeSet;
 import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
+import android.widget.ProgressBar;
 import android.widget.TextView;
 import com.android.internal.logging.MetricsLogger;
 
@@ -51,12 +54,12 @@
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 
-
 /* The task bar view */
 public class TaskViewHeader extends FrameLayout
         implements View.OnClickListener, View.OnLongClickListener {
 
     private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.125f;
+    private static final long FOCUS_INDICATOR_INTERVAL_MS = 30;
 
     /**
      * A color drawable that draws a slight highlight at the top to help it stand out.
@@ -124,6 +127,7 @@
     ImageView mIconView;
     TextView mTitleView;
     int mMoveTaskTargetStackId = INVALID_STACK_ID;
+    ProgressBar mFocusTimerIndicator;
 
     // Header drawables
     Rect mTaskViewRect = new Rect();
@@ -132,9 +136,12 @@
     float mDimAlpha;
     Drawable mLightDismissDrawable;
     Drawable mDarkDismissDrawable;
+    Drawable mLightFreeformIcon;
+    Drawable mDarkFreeformIcon;
+    Drawable mLightFullscreenIcon;
+    Drawable mDarkFullscreenIcon;
     int mTaskBarViewLightTextColor;
     int mTaskBarViewDarkTextColor;
-    String mDismissContentDescription;
 
     // Header background
     private HighlightColorDrawable mBackground;
@@ -145,6 +152,10 @@
     Interpolator mFastOutSlowInInterpolator;
     Interpolator mFastOutLinearInInterpolator;
 
+    long mFocusIndicatorProgress;
+    private CountDownTimer mFocusTimerCountDown;
+    long mFocusTimerDuration;
+
     public TaskViewHeader(Context context) {
         this(context, null);
     }
@@ -165,12 +176,15 @@
         Resources res = context.getResources();
         mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
         mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
-        mDismissContentDescription = context.getString(
-                R.string.accessibility_recents_item_will_be_dismissed);
         mCornerRadius = res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
         mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
         mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
         mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
+        mLightFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_light);
+        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);
+
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_slow_in);
         mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -182,6 +196,7 @@
         setBackground(mBackground);
         mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
         mDimLayerPaint.setAntiAlias(true);
+        mFocusTimerDuration = res.getInteger(R.integer.recents_auto_advance_duration);
     }
 
     @Override
@@ -193,6 +208,7 @@
         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) {
@@ -213,7 +229,9 @@
         mTaskViewRect.set(0, 0, width, height);
         boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE;
         int appIconWidth = mIconView.getMeasuredWidth();
-        int activityDescWidth = mTitleView.getMeasuredWidth();
+        int activityDescWidth = (mTask != null)
+                ? (int) mTitleView.getPaint().measureText(mTask.title)
+                : mTitleView.getMeasuredWidth();
         int dismissIconWidth = mDismissButton.getMeasuredWidth();
         int moveTaskIconWidth = mMoveTaskButton.getVisibility() == View.VISIBLE
                 ? mMoveTaskButton.getMeasuredWidth()
@@ -268,6 +286,41 @@
                 mCornerRadius, mCornerRadius, mDimLayerPaint);
     }
 
+    /** Starts the focus timer. */
+    public void startFocusTimerIndicator() {
+        mFocusTimerIndicator.setVisibility(View.VISIBLE);
+        mFocusTimerIndicator.setMax((int) mFocusTimerDuration);
+        if (mFocusTimerCountDown == null) {
+            mFocusTimerCountDown = new CountDownTimer(mFocusTimerDuration,
+                    FOCUS_INDICATOR_INTERVAL_MS) {
+                public void onTick(long millisUntilFinished) {
+                    mFocusTimerIndicator.setProgress((int) millisUntilFinished);
+                }
+
+                public void onFinish() {
+                    mFocusTimerIndicator.setProgress((int) mFocusTimerDuration);
+                }
+            }.start();
+        } else {
+            mFocusTimerCountDown.start();
+        }
+    }
+
+    /** Cancels the focus timer. */
+    public void cancelFocusTimerIndicator() {
+        if (mFocusTimerCountDown != null && mFocusTimerIndicator != null) {
+            mFocusTimerCountDown.cancel();
+            mFocusTimerIndicator.setProgress(0);
+            mFocusTimerIndicator.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    /** Returns the secondary color for a primary color. */
+    int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) {
+        int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK;
+        return Utilities.getColorWithOverlay(primaryColor, overlayColor, 0.8f);
+    }
+
     /**
      * Sets the dim alpha, only used when we are not using hardware layers.
      * (see RecentsConfiguration.useHardwareLayers)
@@ -307,22 +360,21 @@
                 mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
         mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
                 mLightDismissDrawable : mDarkDismissDrawable);
-        mDismissButton.setContentDescription(String.format(mDismissContentDescription,
-                t.contentDescription));
+        mDismissButton.setContentDescription(t.dismissDescription);
 
         // When freeform workspaces are enabled, then update the move-task button depending on the
         // current task
         if (ssp.hasFreeformWorkspaceSupport()) {
             if (t.isFreeformTask()) {
                 mMoveTaskTargetStackId = FULLSCREEN_WORKSPACE_STACK_ID;
-                mMoveTaskButton.setImageResource(t.useLightOnPrimaryColor
-                        ? R.drawable.recents_move_task_fullscreen_light
-                        : R.drawable.recents_move_task_fullscreen_dark);
+                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
+                        ? mLightFullscreenIcon
+                        : mDarkFullscreenIcon);
             } else {
                 mMoveTaskTargetStackId = FREEFORM_WORKSPACE_STACK_ID;
-                mMoveTaskButton.setImageResource(t.useLightOnPrimaryColor
-                        ? R.drawable.recents_move_task_freeform_light
-                        : R.drawable.recents_move_task_freeform_dark);
+                mMoveTaskButton.setImageDrawable(t.useLightOnPrimaryColor
+                        ? mLightFreeformIcon
+                        : mDarkFreeformIcon);
             }
             if (mMoveTaskButton.getVisibility() != View.VISIBLE) {
                 mMoveTaskButton.setVisibility(View.VISIBLE);
@@ -330,6 +382,11 @@
             mMoveTaskButton.setOnClickListener(this);
         }
 
+        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()) {
             mIconView.setOnClickListener(this);
@@ -359,7 +416,10 @@
         }
     }
 
-    /** Mark this task view that the user does has not interacted with the stack after a certain time. */
+    /**
+     * Mark this task view that the user does has not interacted with the stack after a certain
+     * time.
+     */
     void setNoUserInteractionState() {
         if (mDismissButton.getVisibility() != View.VISIBLE) {
             mDismissButton.animate().cancel();
@@ -368,7 +428,10 @@
         }
     }
 
-    /** Resets the state tracking that the user has not interacted with the stack after a certain time. */
+    /**
+     * Resets the state tracking that the user has not interacted with the stack after a certain
+     * time.
+     */
     void resetNoUserInteractionState() {
         mDismissButton.setVisibility(View.INVISIBLE);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 824d10a..c16703e8 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -363,21 +363,6 @@
         return mStartPosition + touchY - mStartY;
     }
 
-    private int invertDockSide(int dockSide) {
-        switch (dockSide) {
-            case WindowManager.DOCKED_LEFT:
-                return WindowManager.DOCKED_RIGHT;
-            case WindowManager.DOCKED_TOP:
-                return WindowManager.DOCKED_BOTTOM;
-            case WindowManager.DOCKED_RIGHT:
-                return WindowManager.DOCKED_LEFT;
-            case WindowManager.DOCKED_BOTTOM:
-                return WindowManager.DOCKED_TOP;
-            default:
-                return WindowManager.DOCKED_INVALID;
-        }
-    }
-
     private void alignTopLeft(Rect containingRect, Rect rect) {
         int width = rect.width();
         int height = rect.height();
@@ -409,8 +394,9 @@
 
         mLastResizeRect.set(mDockedRect);
         if (taskPosition != TASK_POSITION_SAME) {
-            calculateBoundsForPosition(position, invertDockSide(mDockSide), mOtherRect);
-            int dockSideInverted = invertDockSide(mDockSide);
+            calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
+                    mOtherRect);
+            int dockSideInverted = DockedDividerUtils.invertDockSide(mDockSide);
             int taskPositionDocked =
                     restrictDismissingTaskPosition(taskPosition, mDockSide, taskSnapTarget);
             int taskPositionOther =
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
index 161f873..2294d40 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
@@ -26,6 +26,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
 import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 
 /**
@@ -50,6 +51,7 @@
                         | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY,
                 PixelFormat.TRANSLUCENT);
         mLp.setTitle(WINDOW_TITLE);
+        mLp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
         view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 2791dfc..67bb58a 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -85,7 +85,8 @@
         @Override
         public void run() {
             try {
-                ActivityManagerNative.getDefault().moveTasksToFullscreenStack(DOCKED_STACK_ID);
+                ActivityManagerNative.getDefault().moveTasksToFullscreenStack(
+                        DOCKED_STACK_ID, false /* onTop */);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to remove stack: " + e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 6efb774..ce4eff5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1954,8 +1954,9 @@
                     + " alertAgain=" + alertAgain);
         }
 
+        final StatusBarNotification oldNotification = entry.notification;
         entry.notification = notification;
-        mGroupManager.onEntryUpdated(entry, entry.notification);
+        mGroupManager.onEntryUpdated(entry, oldNotification);
 
         boolean updateSuccessful = false;
         if (applyInPlace) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 3e0ea90..b36fb7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -20,50 +20,92 @@
 import android.app.Dialog;
 import android.content.Context;
 import android.graphics.drawable.ColorDrawable;
-import android.view.Gravity;
+import android.os.Handler;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.KeyboardShortcutInfo;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
+import android.view.WindowManager.KeyboardShortcutsReceiver;
 
 import com.android.systemui.R;
+import com.android.systemui.recents.Recents;
+
+import java.util.List;
+
+import static android.content.Context.LAYOUT_INFLATER_SERVICE;
+import static android.graphics.Color.TRANSPARENT;
+import static android.view.Gravity.TOP;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 
 /**
  * Contains functionality for handling keyboard shortcuts.
  */
 public class KeyboardShortcuts {
+    private static final String TAG = "KeyboardShortcuts";
+
     private Dialog mKeyboardShortcutsDialog;
 
     public KeyboardShortcuts() {}
 
-    public void toggleKeyboardShortcuts(Context context) {
+    public void toggleKeyboardShortcuts(final Context context) {
         if (mKeyboardShortcutsDialog == null) {
-            // Create dialog.
-            AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
-            LayoutInflater inflater = (LayoutInflater) context.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            final View keyboardShortcutsView = inflater.inflate(
-                    R.layout.keyboard_shortcuts_view, null);
-
-            populateKeyboardShortcuts(keyboardShortcutsView.findViewById(
-                    R.id.keyboard_shortcuts_wrapper));
-            dialogBuilder.setView(keyboardShortcutsView);
-            mKeyboardShortcutsDialog = dialogBuilder.create();
-            mKeyboardShortcutsDialog.setCanceledOnTouchOutside(true);
-
-            // Setup window.
-            Window keyboardShortcutsWindow = mKeyboardShortcutsDialog.getWindow();
-            keyboardShortcutsWindow.setType(
-                    WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
-            keyboardShortcutsWindow.setBackgroundDrawable(
-                    new ColorDrawable(android.graphics.Color.TRANSPARENT));
-            keyboardShortcutsWindow.setGravity(Gravity.TOP);
-            mKeyboardShortcutsDialog.show();
+            Recents.getSystemServices().requestKeyboardShortcuts(context,
+                new KeyboardShortcutsReceiver() {
+                    @Override
+                    public void onKeyboardShortcutsReceived(
+                            final List<KeyboardShortcutGroup> result) {
+                        KeyboardShortcutGroup systemGroup = new KeyboardShortcutGroup(
+                            context.getString(R.string.keyboard_shortcut_group_system));
+                        systemGroup.addItem(new KeyboardShortcutInfo(
+                            context.getString(R.string.keyboard_shortcut_group_system_home),
+                            '\u2386', KeyEvent.META_META_ON));
+                        systemGroup.addItem(new KeyboardShortcutInfo(
+                            context.getString(R.string.keyboard_shortcut_group_system_back),
+                            '\u007F', KeyEvent.META_META_ON));
+                        systemGroup.addItem(new KeyboardShortcutInfo(
+                            context.getString(R.string.keyboard_shortcut_group_system_recents),
+                            '\u0009', KeyEvent.META_ALT_ON));
+                        result.add(systemGroup);
+                        Log.i(TAG, "Keyboard shortcuts received: " + String.valueOf(result));
+                        showKeyboardShortcutsDialog(context);
+                    }
+                });
         } else {
             dismissKeyboardShortcutsDialog();
         }
     }
 
+    private void showKeyboardShortcutsDialog(Context context) {
+        // Create dialog.
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
+        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+                LAYOUT_INFLATER_SERVICE);
+        final View keyboardShortcutsView = inflater.inflate(
+                R.layout.keyboard_shortcuts_view, null);
+
+        populateKeyboardShortcuts(keyboardShortcutsView.findViewById(
+                R.id.keyboard_shortcuts_wrapper));
+        dialogBuilder.setView(keyboardShortcutsView);
+        mKeyboardShortcutsDialog = dialogBuilder.create();
+        mKeyboardShortcutsDialog.setCanceledOnTouchOutside(true);
+
+        // Setup window.
+        Window keyboardShortcutsWindow = mKeyboardShortcutsDialog.getWindow();
+        keyboardShortcutsWindow.setType(TYPE_SYSTEM_DIALOG);
+        keyboardShortcutsWindow.setBackgroundDrawable(
+                new ColorDrawable(TRANSPARENT));
+        keyboardShortcutsWindow.setGravity(TOP);
+        keyboardShortcutsView.post(new Runnable() {
+            public void run() {
+                mKeyboardShortcutsDialog.show();
+            }
+        });
+    }
+
     public void dismissKeyboardShortcutsDialog() {
         if (mKeyboardShortcutsDialog != null) {
             mKeyboardShortcutsDialog.dismiss();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 20a6e7c..52326e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -16,10 +16,11 @@
 
 package com.android.systemui.statusbar;
 
-import android.annotation.IdRes;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
@@ -28,13 +29,12 @@
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.RadioButton;
-import android.widget.RadioGroup;
 import android.widget.SeekBar;
 import android.widget.TextView;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 
 /**
@@ -123,10 +123,27 @@
         final TextView topicSummary = ((TextView) row.findViewById(R.id.summary));
         final TextView topicTitle = ((TextView) row.findViewById(R.id.title));
         mSeekBar = (SeekBar) row.findViewById(R.id.seekbar);
-        mSeekBar.setMax(4);
+        boolean systemApp = false;
+        try {
+            final PackageManager pm = BaseStatusBar.getPackageManagerForUser(
+                    getContext(), sbn.getUser().getIdentifier());
+            final PackageInfo info =
+                    pm.getPackageInfo(sbn.getPackageName(), PackageManager.GET_SIGNATURES);
+            systemApp = Utils.isSystemPackage(pm, info);
+        } catch (PackageManager.NameNotFoundException e) {
+            // unlikely.
+        }
+        final int minProgress = systemApp ?
+                NotificationListenerService.Ranking.IMPORTANCE_LOW
+                : NotificationListenerService.Ranking.IMPORTANCE_NONE;
+        mSeekBar.setMax(NotificationListenerService.Ranking.IMPORTANCE_MAX);
         mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
             @Override
             public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                if (progress < minProgress) {
+                    seekBar.setProgress(minProgress);
+                    progress = minProgress;
+                }
                 updateTitleAndSummary(progress);
                 if (fromUser) {
                     if (appUsesTopics) {
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/car/CarNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
new file mode 100644
index 0000000..3e2c4c6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.car;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.support.v4.util.SimpleArrayMap;
+import android.view.View;
+import android.widget.LinearLayout;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.ActivityStarter;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A controller to populate data for CarNavigationBarView and handle user interactions.
+ * <p/>
+ * Each button inside the navigation bar is defined by data in arrays_car.xml. OEMs can customize
+ * the navigation buttons by updating arrays_car.xml appropriately in an overlay.
+ */
+class CarNavigationBarController {
+
+    // Each facet of the navigation bar maps to a set of package names or categories defined in
+    // arrays_car.xml. Package names for a given facet are delimited by ";"
+    private static final String FACET_FILTER_DEMILITER = ";";
+
+    private Context mContext;
+    private CarNavigationBarView mNavBar;
+    private ActivityStarter mActivityStarter;
+
+    // Set of categories each facet will filter on.
+    private List<String[]> mFacetCategories = new ArrayList<String[]>();
+    // Set of package names each facet will filter on.
+    private List<String[]> mFacetPackages = new ArrayList<String[]>();
+
+    private SimpleArrayMap<String, Integer> mFacetCategoryMap
+            = new SimpleArrayMap<String, Integer>();
+    private SimpleArrayMap<String, Integer> mFacetPackageMap
+            = new SimpleArrayMap<String, Integer>();
+
+    private List<Intent> mIntents = new ArrayList<Intent>();
+    private List<Intent> mLongPressIntents = new ArrayList<Intent>();
+
+    private List<CarNavigationButton> mNavButtons = new ArrayList<CarNavigationButton>();
+
+    private int mCurrentFacetIndex;
+
+    public CarNavigationBarController(Context context,
+                                      CarNavigationBarView navBar,
+                                      ActivityStarter activityStarter) {
+        mContext = context;
+        mNavBar = navBar;
+        mActivityStarter = activityStarter;
+        bind();
+    }
+
+    public void taskChanged(String packageName) {
+        // If the package name belongs to a filter, then highlight appropriate button in
+        // the navigation bar.
+        if (mFacetPackageMap.containsKey(packageName)) {
+            setCurrentFacet(mFacetPackageMap.get(packageName));
+        }
+
+        // Check if the package matches any of the categories for the facets
+        String category = getPackageCategory(packageName);
+        if (category != null) {
+            setCurrentFacet(mFacetCategoryMap.get(category));
+        }
+    }
+
+    private void bind() {
+        // Read up arrays_car.xml and populate the navigation bar here.
+        Resources r = mContext.getResources();
+        TypedArray icons = r.obtainTypedArray(R.array.car_facet_icons);
+        TypedArray intents = r.obtainTypedArray(R.array.car_facet_intent_uris);
+        TypedArray longpressIntents =
+                r.obtainTypedArray(R.array.car_facet_longpress_intent_uris);
+        TypedArray facetPackageNames = r.obtainTypedArray(R.array.car_facet_package_filters);
+
+        TypedArray facetCategories = r.obtainTypedArray(R.array.car_facet_category_filters);
+
+        if (icons.length() != intents.length()
+                || icons.length() != longpressIntents.length()
+                || icons.length() != facetPackageNames.length()
+                || icons.length() != facetCategories.length()) {
+            throw new RuntimeException("car_facet array lengths do not match");
+        }
+
+        for (int i = 0; i < icons.length(); i++) {
+            Drawable icon = icons.getDrawable(i);
+            try {
+                mIntents.add(i,
+                        Intent.parseUri(intents.getString(i), Intent.URI_INTENT_SCHEME));
+
+                String longpressUri = longpressIntents.getString(i);
+                boolean hasLongpress = !longpressUri.isEmpty();
+                if (hasLongpress) {
+                    mLongPressIntents.add(i,
+                            Intent.parseUri(longpressUri, Intent.URI_INTENT_SCHEME));
+                }
+
+                CarNavigationButton button = createNavButton(icon, i, hasLongpress);
+                mNavButtons.add(button);
+                mNavBar.addButton(button, createNavButton(icon, i, hasLongpress));
+
+                initFacetFilterMaps(i,
+                        facetPackageNames.getString(i).split(FACET_FILTER_DEMILITER),
+                        facetCategories.getString(i).split(FACET_FILTER_DEMILITER));
+            } catch (URISyntaxException e) {
+                throw new RuntimeException("Malformed intent uri", e);
+            }
+        }
+    }
+
+    private void initFacetFilterMaps(int id, String[] packageNames, String[] categories){
+        mFacetCategories.add(categories);
+        for (int i = 0; i < categories.length; i++) {
+            mFacetCategoryMap.put(categories[i], id);
+        }
+
+        mFacetPackages.add(packageNames);
+        for (int i = 0; i < packageNames.length; i++) {
+            mFacetPackageMap.put(packageNames[i], id);
+        }
+    }
+
+    private String getPackageCategory(String packageName) {
+        PackageManager pm = mContext.getPackageManager();
+        int size = mFacetCategories.size();
+        // For each facet, check if the given package name matches one of its categories
+        for (int i = 0; i < size; i++) {
+            String[] categories = mFacetCategories.get(i);
+            for (int j = 0; j < categories.length; j++) {
+                String category = categories[j];
+                Intent intent = new Intent();
+                intent.setPackage(packageName);
+                intent.setAction(Intent.ACTION_MAIN);
+                intent.addCategory(category);
+                List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
+                if (list.size() > 0) {
+                    // Cache this package name into facetPackageMap, so we won't have to query
+                    // all categories next time this package name shows up.
+                    mFacetPackageMap.put(packageName, mFacetCategoryMap.get(category));
+                    return category;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Helper method to check if a given facet has multiple packages associated with it.
+     * This can be resource defined package names or package names filtered by facet category.
+     */
+    private boolean facetHasMultiplePackages(int index) {
+        PackageManager pm = mContext.getPackageManager();
+
+        // Check if the packages defined for the filter actually exists on the device
+        String[] packages = mFacetPackages.get(index);
+        if (packages.length > 1) {
+            int count = 0;
+            for (int i = 0; i < packages.length; i++) {
+                count += pm.getLaunchIntentForPackage(packages[i]) != null ? 1 : 0;
+                if (count > 1) {
+                    return true;
+                }
+            }
+        }
+
+        // If there weren't multiple packages defined for the facet, check the categories
+        // and see if they resolve to multiple package names
+        String categories[] = mFacetCategories.get(index);
+
+        int count = 0;
+        for (int i = 0; i < categories.length; i++) {
+            String category = categories[i];
+            Intent intent = new Intent();
+            intent.setAction(Intent.ACTION_MAIN);
+            intent.addCategory(category);
+            count += pm.queryIntentActivities(intent, 0).size();
+            if (count > 1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void setCurrentFacet(int index) {
+        if (index == mCurrentFacetIndex) {
+            return;
+        }
+
+        if (mNavButtons.get(mCurrentFacetIndex) != null) {
+            mNavButtons.get(mCurrentFacetIndex)
+                    .setSelected(false /* selected */, false /* showMoreIcon */);
+        }
+
+        if (mNavButtons.get(index) != null) {
+            mNavButtons.get(index).setSelected(true /* selected */,
+                    facetHasMultiplePackages(index)  /* showMoreIcon */);
+        }
+        mCurrentFacetIndex = index;
+    }
+
+    private CarNavigationButton createNavButton(Drawable icon, final int id,
+                                                boolean longClickEnabled) {
+        CarNavigationButton button = (CarNavigationButton) View.inflate(mContext,
+                R.layout.car_navigation_button, null);
+        button.setResources(icon);
+        LinearLayout.LayoutParams lp =
+                new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
+        button.setLayoutParams(lp);
+
+        button.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setCurrentFacet(id);
+                onFacetClicked(id);
+            }
+        });
+
+        if (longClickEnabled) {
+            button.setLongClickable(true);
+            button.setOnLongClickListener(new View.OnLongClickListener() {
+                @Override
+                public boolean onLongClick(View v) {
+                    onFacetLongClicked(id);
+                    setCurrentFacet(id);
+                    return true;
+                }
+            });
+        } else {
+            button.setLongClickable(false);
+        }
+        return button;
+    }
+
+    private void startActivity(Intent intent) {
+        if (mActivityStarter != null && intent != null) {
+            mActivityStarter.startActivity(intent, true);
+        }
+    }
+
+    private void onFacetClicked(int index) {
+        // TODO: determine what data to pass to the trampoline, so it can start
+        // the default app or the lens picker.
+        startActivity(mIntents.get(index));
+    }
+
+    private void onFacetLongClicked(int index) {
+        // TODO: determine what data to pass to the trampoline, so it can start
+        // the default app or the lens picker.
+        startActivity(mLongPressIntents.get(index));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
index e2d64b04..efc3646 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
@@ -17,36 +17,29 @@
 package com.android.systemui.statusbar.car;
 
 import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.R.color;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.widget.ImageButton;
 import android.widget.ImageView.ScaleType;
 import android.widget.LinearLayout;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.ActivityStarter;
 import com.android.systemui.statusbar.phone.NavigationBarView;
-import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
-import com.android.systemui.statusbar.policy.KeyButtonView;
 
-import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
 
 /**
  * A custom navigation bar for the automotive use case.
  * <p>
- * The navigation bar in the automotive use case is more like a list of shortcuts, which we
- * expect to be customizable by the car OEMs. This implementation populates the nav_buttons layout
- * from resources rather than the layout file so customization would then mean updating
- * arrays_car.xml appropriately in an overlay.
+ * The navigation bar in the automotive use case is more like a list of shortcuts, rendered
+ * in a linear layout.
  */
 class CarNavigationBarView extends NavigationBarView {
-    private ActivityStarter mActivityStarter;
+    private LinearLayout mNavButtons;
+    private LinearLayout mLightsOutButtons;
 
     public CarNavigationBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -54,83 +47,13 @@
 
     @Override
     public void onFinishInflate() {
-        // Read up arrays_car.xml and populate the navigation bar here.
-        Context context = getContext();
-        Resources r = getContext().getResources();
-        TypedArray icons = r.obtainTypedArray(R.array.car_shortcut_icons);
-        TypedArray intents = r.obtainTypedArray(R.array.car_shortcut_intent_uris);
-        TypedArray longpressIntents =
-                r.obtainTypedArray(R.array.car_shortcut_longpress_intent_uris);
-
-        if (icons.length() != intents.length()) {
-            throw new RuntimeException("car_shortcut_icons and car_shortcut_intents do not match");
-        }
-
-        LinearLayout navButtons = (LinearLayout) findViewById(R.id.nav_buttons);
-        LinearLayout lightsOut = (LinearLayout) findViewById(R.id.lights_out);
-
-        for (int i = 0; i < icons.length(); i++) {
-            Drawable icon = icons.getDrawable(i);
-
-            try {
-                Intent intent = Intent.parseUri(intents.getString(i), Intent.URI_INTENT_SCHEME);
-                Intent longpress = null;
-                String longpressUri = longpressIntents.getString(i);
-                if (!longpressUri.isEmpty()) {
-                    longpress = Intent.parseUri(longpressUri, Intent.URI_INTENT_SCHEME);
-                }
-
-                // nav_buttons and lights_out should match exactly.
-                navButtons.addView(makeButton(context, icon, intent, longpress));
-                lightsOut.addView(makeButton(context, icon, intent, longpress));
-            } catch (URISyntaxException e) {
-                throw new RuntimeException("Malformed intent uri", e);
-            }
-        }
+        mNavButtons = (LinearLayout) findViewById(R.id.nav_buttons);
+        mLightsOutButtons = (LinearLayout) findViewById(R.id.lights_out);
     }
 
-    private ImageButton makeButton(Context context, Drawable icon,
-            final Intent intent, final Intent longpress) {
-        ImageButton button = new ImageButton(context);
-
-        button.setImageDrawable(icon);
-        button.setScaleType(ScaleType.CENTER);
-        button.setBackgroundColor(color.transparent);
-        LinearLayout.LayoutParams lp =
-                new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
-        button.setLayoutParams(lp);
-
-        button.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mActivityStarter != null) {
-                    mActivityStarter.startActivity(intent, true);
-                }
-            }
-        });
-
-        // Long click handlers are optional.
-        if (longpress != null) {
-            button.setLongClickable(true);
-            button.setOnLongClickListener(new OnLongClickListener() {
-                @Override
-                public boolean onLongClick(View v) {
-                    if (mActivityStarter != null) {
-                        mActivityStarter.startActivity(longpress, true);
-                        return true;
-                    }
-                    return false;
-                }
-            });
-        } else {
-            button.setLongClickable(false);
-        }
-
-        return button;
-    }
-
-    public void setActivityStarter(ActivityStarter activityStarter) {
-        mActivityStarter = activityStarter;
+    public void addButton(CarNavigationButton button, CarNavigationButton lightsOutButton){
+        mNavButtons.addView(button);
+        mLightsOutButtons.addView(lightsOutButton);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
new file mode 100644
index 0000000..36b3a8a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.car;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import com.android.keyguard.AlphaOptimizedImageButton;
+import com.android.systemui.R;
+
+/**
+ * A wrapper view for a car navigation facet, which includes a button icon and a drop down icon.
+ */
+public class CarNavigationButton extends RelativeLayout {
+    private static final float SELECTED_ALPHA = 1;
+    private static final float UNSELECTED_ALPHA = 0.7f;
+
+    private AlphaOptimizedImageButton mIcon;
+    private AlphaOptimizedImageButton mMoreIcon;
+
+    public CarNavigationButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void onFinishInflate() {
+        super.onFinishInflate();
+        mIcon = (AlphaOptimizedImageButton) findViewById(R.id.car_nav_button_icon);
+        mIcon.setClickable(false);
+        mIcon.setScaleType(ImageView.ScaleType.CENTER);
+        mIcon.setBackgroundColor(android.R.color.transparent);
+        mIcon.setAlpha(UNSELECTED_ALPHA);
+
+        mMoreIcon = (AlphaOptimizedImageButton) findViewById(R.id.car_nav_button_more_icon);
+        mMoreIcon.setClickable(false);
+        mMoreIcon.setScaleType(ImageView.ScaleType.CENTER);
+        mMoreIcon.setBackgroundColor(android.R.color.transparent);
+        mMoreIcon.setVisibility(INVISIBLE);
+        mMoreIcon.setImageDrawable(getContext().getDrawable(R.drawable.car_ic_arrow));
+        mMoreIcon.setAlpha(UNSELECTED_ALPHA);
+    }
+
+    public void setResources(Drawable icon) {
+        mIcon.setImageDrawable(icon);
+    }
+
+    public void setSelected(boolean selected, boolean showMoreIcon) {
+        if (selected) {
+            mMoreIcon.setVisibility(showMoreIcon ? VISIBLE : INVISIBLE);
+            mMoreIcon.setAlpha(SELECTED_ALPHA);
+            mIcon.setAlpha(SELECTED_ALPHA);
+        } else {
+            mMoreIcon.setVisibility(INVISIBLE);
+            mIcon.setAlpha(UNSELECTED_ALPHA);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 31631f8..f6f1f94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -16,30 +16,52 @@
 
 package com.android.systemui.statusbar.car;
 
+import android.app.ActivityManager;
+import android.app.ITaskStackListener;
 import android.content.Context;
 import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.Looper;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 
 import com.android.systemui.R;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 /**
  * A status bar (and navigation bar) tailored for the automotive use case.
  */
 public class CarStatusBar extends PhoneStatusBar {
+    private SystemServicesProxy mSystemServicesProxy;
+    private TaskStackListenerImpl mTaskStackListener;
+    private Handler mHandler;
+
+    private CarNavigationBarView mCarNavigationBar;
+    private CarNavigationBarController mController;
+
+    @Override
+    public void start() {
+        super.start();
+        mHandler = new Handler();
+        mTaskStackListener = new TaskStackListenerImpl(mHandler);
+        mSystemServicesProxy = new SystemServicesProxy(mContext);
+        mSystemServicesProxy.registerTaskStackListener(mTaskStackListener);
+    }
+
     @Override
     protected void addNavigationBar() {
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
-                    WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
-                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+                WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                 PixelFormat.TRANSLUCENT);
         lp.setTitle("CarNavigationBar");
         lp.windowAnimations = 0;
@@ -51,11 +73,11 @@
         if (mNavigationBarView != null) {
             return;
         }
-
-        CarNavigationBarView carNavBar =
+        mCarNavigationBar =
                 (CarNavigationBarView) View.inflate(context, R.layout.car_navigation_bar, null);
-        carNavBar.setActivityStarter(this);
-        mNavigationBarView = carNavBar;
+        mController = new CarNavigationBarController(context, mCarNavigationBar,
+                this /* ActivityStarter*/);
+        mNavigationBarView = mCarNavigationBar;
     }
 
     @Override
@@ -63,4 +85,40 @@
         // The navigation bar for a vehicle will not need to be repositioned, as it is always
         // set at the bottom.
     }
+
+    /**
+     * An implementation of ITaskStackListener, that listens for changes in the system task
+     * stack and notifies the navigation bar.
+     */
+    private class TaskStackListenerImpl extends ITaskStackListener.Stub implements Runnable {
+        private Handler mHandler;
+
+        public TaskStackListenerImpl(Handler handler) {
+            this.mHandler = handler;
+        }
+
+        @Override
+        public void onActivityPinned() {
+        }
+
+        @Override
+        public void onTaskStackChanged() {
+            mHandler.removeCallbacks(this);
+            mHandler.post(this);
+        }
+
+        @Override
+        public void run() {
+            ensureMainThread();
+            SystemServicesProxy ssp = Recents.getSystemServices();
+            ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getTopMostTask();
+            mController.taskChanged(runningTaskInfo.baseActivity.getPackageName());
+        }
+
+        private void ensureMainThread() {
+            if (!Looper.getMainLooper().isCurrentThread()) {
+                throw new RuntimeException("Must be called on the UI thread");
+            }
+        }
+    }
 }
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/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 99436a1..347ba3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -41,13 +41,13 @@
  */
 public class KeyguardBouncer {
 
-    private Context mContext;
-    private ViewMediatorCallback mCallback;
-    private LockPatternUtils mLockPatternUtils;
-    private ViewGroup mContainer;
+    protected Context mContext;
+    protected ViewMediatorCallback mCallback;
+    protected LockPatternUtils mLockPatternUtils;
+    protected ViewGroup mContainer;
     private StatusBarWindowManager mWindowManager;
-    private KeyguardHostView mKeyguardView;
-    private ViewGroup mRoot;
+    protected KeyguardHostView mKeyguardView;
+    protected ViewGroup mRoot;
     private boolean mShowingSoon;
     private int mBouncerPromptReason;
     private FalsingManager mFalsingManager;
@@ -134,7 +134,7 @@
     public void hide(boolean destroyView) {
         mFalsingManager.onBouncerHidden();
         cancelShowRunnable();
-         if (mKeyguardView != null) {
+        if (mKeyguardView != null) {
             mKeyguardView.cancelDismissAction();
             mKeyguardView.cleanUp();
         }
@@ -184,13 +184,13 @@
         mBouncerPromptReason = mCallback.getBouncerPromptReason();
     }
 
-    private void ensureView() {
+    protected void ensureView() {
         if (mRoot == null) {
             inflateView();
         }
     }
 
-    private void inflateView() {
+    protected void inflateView() {
         removeView();
         mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
         mKeyguardView = (KeyguardHostView) mRoot.findViewById(R.id.keyguard_host_view);
@@ -201,7 +201,7 @@
         mRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
     }
 
-    private void removeView() {
+    protected void removeView() {
         if (mRoot != null && mRoot.getParent() == mContainer) {
             mContainer.removeView(mRoot);
             mRoot = 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 e5b4f4d..2db0804 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -23,6 +23,7 @@
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
+import android.view.View;
 import android.view.ViewConfiguration;
 
 import com.android.internal.logging.MetricsLogger;
@@ -55,6 +56,7 @@
     private RecentsComponent mRecentsComponent;
     private Divider mDivider;
     private Context mContext;
+    private NavigationBarView mNavigationBarView;
     private boolean mIsVertical;
     private boolean mIsRTL;
 
@@ -63,6 +65,7 @@
     private final int mMinFlingVelocity;
     private int mTouchDownX;
     private int mTouchDownY;
+    private boolean mDownOnRecents;
     private VelocityTracker mVelocityTracker;
 
     private boolean mDockWindowEnabled;
@@ -79,9 +82,11 @@
         TunerService.get(context).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
     }
 
-    public void setComponents(RecentsComponent recentsComponent, Divider divider) {
+    public void setComponents(RecentsComponent recentsComponent, Divider divider,
+            NavigationBarView navigationBarView) {
         mRecentsComponent = recentsComponent;
         mDivider = divider;
+        mNavigationBarView = navigationBarView;
     }
 
     public void setBarState(boolean isVertical, boolean isRTL) {
@@ -157,6 +162,11 @@
         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();
     }
 
     private boolean handleDragActionMoveEvent(MotionEvent event) {
@@ -172,8 +182,8 @@
             boolean touchSlopExceeded = !mIsVertical
                     ? yDiff > mScrollTouchSlop && yDiff > xDiff
                     : xDiff > mScrollTouchSlop && xDiff > yDiff;
-            if (touchSlopExceeded && mDivider.getView().getWindowManagerProxy().getDockSide()
-                    == DOCKED_INVALID) {
+            if (mDownOnRecents && touchSlopExceeded
+                    && mDivider.getView().getWindowManagerProxy().getDockSide() == DOCKED_INVALID) {
                 Rect initialBounds = null;
                 int dragMode = calculateDragMode();
                 int createMode = ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
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 55c7cb7..efa8f5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -197,7 +197,7 @@
     }
 
     public void setComponents(RecentsComponent recentsComponent, Divider divider) {
-        mGestureHelper.setComponents(recentsComponent, divider);
+        mGestureHelper.setComponents(recentsComponent, divider, this);
     }
 
     public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
@@ -231,6 +231,10 @@
         return mCurrentView;
     }
 
+    public View[] getAllViews() {
+        return mRotatedViews;
+    }
+
     public KeyButtonView getRecentsButton() {
         return (KeyButtonView) getCurrentView().findViewById(R.id.recent_apps);
     }
@@ -341,7 +345,6 @@
         // Update menu button in case the IME state has changed.
         setMenuVisibility(mShowMenu, true);
 
-
         setDisabledFlags(mDisabledFlags, true);
     }
 
@@ -398,12 +401,6 @@
         }
     }
 
-    private void setVisibleOrGone(View view, boolean visible) {
-        if (view != null) {
-            view.setVisibility(visible ? VISIBLE : GONE);
-        }
-    }
-
     public void setLayoutTransitionsEnabled(boolean enabled) {
         mLayoutTransitionsEnabled = enabled;
         updateLayoutTransitionsEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
new file mode 100644
index 0000000..405ef05
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -0,0 +1,151 @@
+package com.android.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import com.android.internal.util.NotificationColorUtil;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.notification.NotificationUtils;
+
+import java.util.ArrayList;
+
+/**
+ * A controller for the space in the status bar to the left of the system icons. This area is
+ * normally reserved for notifications.
+ */
+public class NotificationIconAreaController {
+    private final NotificationColorUtil mNotificationColorUtil;
+
+    private int mIconSize;
+    private int mIconHPadding;
+    private int mIconTint = Color.WHITE;
+
+    private PhoneStatusBar mPhoneStatusBar;
+    protected View mNotificationIconArea;
+    private IconMerger mNotificationIcons;
+    private ImageView mMoreIcon;
+
+    public NotificationIconAreaController(Context context, PhoneStatusBar phoneStatusBar) {
+        mPhoneStatusBar = phoneStatusBar;
+        mNotificationColorUtil = NotificationColorUtil.getInstance(context);
+
+        initializeNotificationAreaViews(context);
+    }
+
+    /**
+     * Initializes the views that will represent the notification area.
+     */
+    protected void initializeNotificationAreaViews(Context context) {
+        Resources res = context.getResources();
+        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+        mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
+
+        LayoutInflater layoutInflater = LayoutInflater.from(context);
+        mNotificationIconArea = layoutInflater.inflate(R.layout.notification_icon_area, null);
+
+        mMoreIcon = (ImageView) mNotificationIconArea.findViewById(R.id.moreIcon);
+        mMoreIcon.setImageTintList(ColorStateList.valueOf(mIconTint));
+
+        mNotificationIcons =
+                (IconMerger) mNotificationIconArea.findViewById(R.id.notificationIcons);
+        mNotificationIcons.setOverflowIndicator(mMoreIcon);
+    }
+
+    /**
+     * Returns the view that represents the notification area.
+     */
+    public View getNotificationInnerAreaView() {
+        return mNotificationIconArea;
+    }
+
+    /**
+     * Sets the color that should be used to tint any icons in the notification area. If this
+     * method is not called, the default tint is {@link Color#WHITE}.
+     */
+    public void setIconTint(int iconTint) {
+        mIconTint = iconTint;
+        mMoreIcon.setImageTintList(ColorStateList.valueOf(mIconTint));
+        applyNotificationIconsTint();
+    }
+
+    /**
+     * Updates the notifications with the given list of notifications to display.
+     */
+    public void updateNotificationIcons(NotificationData notificationData) {
+        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+                mIconSize + 2 * mIconHPadding, mPhoneStatusBar.getStatusBarHeight());
+
+        ArrayList<NotificationData.Entry> activeNotifications =
+                notificationData.getActiveNotifications();
+        final int size = activeNotifications.size();
+        ArrayList<StatusBarIconView> toShow = new ArrayList<>(size);
+
+        // Filter out ambient notifications and notification children.
+        for (int i = 0; i < size; i++) {
+            NotificationData.Entry ent = activeNotifications.get(i);
+            if (notificationData.isAmbient(ent.key)
+                    && !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
+                continue;
+            }
+            if (!PhoneStatusBar.isTopLevelChild(ent)) {
+                continue;
+            }
+            toShow.add(ent.icon);
+        }
+
+        ArrayList<View> toRemove = new ArrayList<>();
+        for (int i = 0; i < mNotificationIcons.getChildCount(); i++) {
+            View child = mNotificationIcons.getChildAt(i);
+            if (!toShow.contains(child)) {
+                toRemove.add(child);
+            }
+        }
+
+        final int toRemoveCount = toRemove.size();
+        for (int i = 0; i < toRemoveCount; i++) {
+            mNotificationIcons.removeView(toRemove.get(i));
+        }
+
+        for (int i = 0; i < toShow.size(); i++) {
+            View v = toShow.get(i);
+            if (v.getParent() == null) {
+                mNotificationIcons.addView(v, i, params);
+            }
+        }
+
+        // Re-sort notification icons
+        final int childCount = mNotificationIcons.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View actual = mNotificationIcons.getChildAt(i);
+            StatusBarIconView expected = toShow.get(i);
+            if (actual == expected) {
+                continue;
+            }
+            mNotificationIcons.removeView(expected);
+            mNotificationIcons.addView(expected, i);
+        }
+
+        applyNotificationIconsTint();
+    }
+
+    /**
+     * Applies {@link #mIconTint} to the notification icons.
+     */
+    private void applyNotificationIconsTint() {
+        for (int i = 0; i < mNotificationIcons.getChildCount(); i++) {
+            StatusBarIconView v = (StatusBarIconView) mNotificationIcons.getChildAt(i);
+            boolean isPreL = Boolean.TRUE.equals(v.getTag(R.id.icon_is_pre_L));
+            boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mNotificationColorUtil);
+            if (colorize) {
+                v.setImageTintList(ColorStateList.valueOf(mIconTint));
+            }
+        }
+    }
+}
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 50e88d3..8a5cf26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -82,6 +82,7 @@
 import android.view.MotionEvent;
 import android.view.ThreadedRenderer;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewStub;
 import android.view.WindowManager;
@@ -268,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;
@@ -279,9 +280,9 @@
     VolumeComponent mVolumeComponent;
     KeyguardUserSwitcher mKeyguardUserSwitcher;
     FlashlightController mFlashlightController;
-    UserSwitcherController mUserSwitcherController;
+    protected UserSwitcherController mUserSwitcherController;
     NextAlarmController mNextAlarmController;
-    KeyguardMonitor mKeyguardMonitor;
+    protected KeyguardMonitor mKeyguardMonitor;
     BrightnessMirrorController mBrightnessMirrorController;
     AccessibilityController mAccessibilityController;
     FullscreenUserSwitcher mFullscreenUserSwitcher;
@@ -295,7 +296,7 @@
     StatusBarWindowView mStatusBarWindow;
     PhoneStatusBarView mStatusBarView;
     private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
-    private StatusBarWindowManager mStatusBarWindowManager;
+    protected StatusBarWindowManager mStatusBarWindowManager;
     private UnlockMethodCache mUnlockMethodCache;
     private DozeServiceHost mDozeServiceHost;
     private boolean mWakeUpComingFromTouch;
@@ -422,8 +423,8 @@
     private int mMaxKeyguardNotifications;
 
     private ViewMediatorCallback mKeyguardViewMediatorCallback;
-    private ScrimController mScrimController;
-    private DozeScrimController mDozeScrimController;
+    protected ScrimController mScrimController;
+    protected DozeScrimController mDozeScrimController;
 
     private final Runnable mAutohide = new Runnable() {
         @Override
@@ -437,7 +438,7 @@
     private boolean mWaitingForKeyguardExit;
     private boolean mDozing;
     private boolean mDozingRequested;
-    private boolean mScrimSrcModeEnabled;
+    protected boolean mScrimSrcModeEnabled;
 
     private Interpolator mLinearInterpolator = new LinearInterpolator();
     private Interpolator mBackdropInterpolator = new AccelerateDecelerateInterpolator();
@@ -494,7 +495,6 @@
 
     private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
 
-    private int mDrawCount;
     private Runnable mLaunchTransitionEndRunnable;
     private boolean mLaunchTransitionFadingAway;
     private ExpandableNotificationRow mDraggedDownRow;
@@ -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
 
@@ -669,8 +670,6 @@
     protected PhoneStatusBarView makeStatusBarView() {
         final Context context = mContext;
 
-        Resources res = context.getResources();
-
         updateDisplaySize(); // populates mDisplayMetrics
         updateResources();
 
@@ -834,23 +833,11 @@
             mZenModeController = mVolumeComponent.getZenController();
         }
         mCastController = new CastControllerImpl(mContext);
-        final SignalClusterView signalCluster =
-                (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
-        final SignalClusterView signalClusterKeyguard =
-                (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
-        final SignalClusterView signalClusterQs =
-                (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
-        mNetworkController.addSignalCallback(signalCluster);
-        mNetworkController.addSignalCallback(signalClusterKeyguard);
-        signalCluster.setSecurityController(mSecurityController);
-        signalCluster.setNetworkController(mNetworkController);
-        signalClusterKeyguard.setSecurityController(mSecurityController);
-        signalClusterKeyguard.setNetworkController(mNetworkController);
-        if (signalClusterQs != null) {
-            mNetworkController.addSignalCallback(signalClusterQs);
-            signalClusterQs.setSecurityController(mSecurityController);
-            signalClusterQs.setNetworkController(mNetworkController);
-        }
+
+        initSignalCluster(mStatusBarView);
+        initSignalCluster(mKeyguardStatusBar);
+        initSignalCluster(mHeader);
+
         final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
         if (isAPhone) {
             mNetworkController.addEmergencyListener(mHeader);
@@ -866,7 +853,7 @@
         mKeyguardMonitor = new KeyguardMonitor(mContext);
         if (UserManager.get(mContext).isUserSwitcherEnabled()) {
             mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
-                    mHandler);
+                    mHandler, this);
             if (mUserSwitcherController.useFullscreenUserSwitcher()) {
                 mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController,
                         (ViewStub) mStatusBarWindow.findViewById(
@@ -948,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(
@@ -976,6 +956,27 @@
             }});
     }
 
+    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) {
+            mNetworkController.addSignalCallback(signalCluster);
+            signalCluster.setSecurityController(mSecurityController);
+            signalCluster.setNetworkController(mNetworkController);
+        }
+    }
+
     /** Returns true if the app shelf should be shown in the nav bar. */
     private boolean shouldShowAppShelf() {
         // Allow adb to override the default shelf behavior:
@@ -1072,13 +1073,13 @@
         }
     }
 
-    private void startKeyguard() {
+    protected void startKeyguard() {
         KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
         mFingerprintUnlockController = new FingerprintUnlockController(mContext,
                 mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
                 mScrimController, this);
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
-                mStatusBarWindow, mStatusBarWindowManager, mScrimController,
+                getBouncerContainer(), mStatusBarWindowManager, mScrimController,
                 mFingerprintUnlockController);
         mKeyguardIndicationController.setStatusBarKeyguardViewManager(
                 mStatusBarKeyguardViewManager);
@@ -1096,6 +1097,10 @@
         return mStatusBarWindow;
     }
 
+    protected ViewGroup getBouncerContainer() {
+        return mStatusBarWindow;
+    }
+
     public int getStatusBarHeight() {
         if (mNaturalBarHeight < 0) {
             final Resources res = mContext.getResources();
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 336b208..7e27856 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -27,6 +27,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.external.CustomTile;
@@ -99,6 +100,7 @@
     private final TileServices mServices;
 
     private final List<Callback> mCallbacks = new ArrayList<>();
+    private View mHeader;
 
     public QSTileHost(Context context, PhoneStatusBar statusBar,
                       BluetoothController bluetooth, LocationController location,
@@ -135,6 +137,10 @@
         TunerService.get(mContext).addTunable(this, TILES_SETTING);
     }
 
+    public void setHeaderView(View view) {
+        mHeader = view;
+    }
+
     public PhoneStatusBar getPhoneStatusBar() {
         return mStatusBar;
     }
@@ -173,6 +179,11 @@
         // already logged
     }
 
+    public void animateExpandQS() {
+        // TODO: Better path to animated panel expansion.
+        mHeader.performClick();
+    }
+
     @Override
     public void collapsePanels() {
         mStatusBar.postAnimateCollapsePanels();
@@ -284,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/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index 3692aee..5b44f0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -197,23 +197,16 @@
         }
     }
 
-    public void setupHost(QSTileHost host) {
-        final QSTileHost myHost = new QSTileHost(host.getContext(), host.getPhoneStatusBar(),
-                host.getBluetoothController(), host.getLocationController(),
-                host.getRotationLockController(), host.getNetworkController(),
-                host.getZenModeController(), host.getHotspotController(),
-                host.getCastController(), host.getFlashlightController(),
-                host.getUserSwitcherController(), host.getUserInfoController(),
-                host.getKeyguardMonitor(), host.getSecurityController(),
-                host.getBatteryController(), host.getIconController());
+    public void setupHost(final QSTileHost host) {
+        host.setHeaderView(this);
         mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this);
-        mHeaderQsPanel.setHost(myHost);
+        mHeaderQsPanel.setHost(host);
         mHeaderQsPanel.setMaxTiles(5);
-        mHeaderQsPanel.setTiles(myHost.getTiles());
-        myHost.addCallback(new QSTile.Host.Callback() {
+        mHeaderQsPanel.setTiles(host.getTiles());
+        host.addCallback(new QSTile.Host.Callback() {
             @Override
             public void onTilesChanged() {
-                mHeaderQsPanel.setTiles(myHost.getTiles());
+                mHeaderQsPanel.setTiles(host.getTiles());
             }
         });
     }
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 5e98ec1..b16c98e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -36,14 +36,12 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarIconView;
-import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -66,15 +64,15 @@
     private Interpolator mLinearOutSlowIn;
     private Interpolator mFastOutSlowIn;
     private DemoStatusIcons mDemoStatusIcons;
-    private NotificationColorUtil mNotificationColorUtil;
 
     private LinearLayout mSystemIconArea;
     private LinearLayout mStatusIcons;
     private SignalClusterView mSignalCluster;
     private LinearLayout mStatusIconsKeyguard;
-    private IconMerger mNotificationIcons;
-    private View mNotificationIconArea;
-    private ImageView mMoreIcon;
+
+    private NotificationIconAreaController mNotificationIconAreaController;
+    private View mNotificationIconAreaInner;
+
     private BatteryMeterView mBatteryMeterView;
     private TextView mClock;
 
@@ -110,14 +108,19 @@
             PhoneStatusBar phoneStatusBar) {
         mContext = context;
         mPhoneStatusBar = phoneStatusBar;
-        mNotificationColorUtil = NotificationColorUtil.getInstance(context);
         mSystemIconArea = (LinearLayout) statusBar.findViewById(R.id.system_icon_area);
         mStatusIcons = (LinearLayout) statusBar.findViewById(R.id.statusIcons);
         mSignalCluster = (SignalClusterView) statusBar.findViewById(R.id.signal_cluster);
-        mNotificationIconArea = statusBar.findViewById(R.id.notification_icon_area_inner);
-        mNotificationIcons = (IconMerger) statusBar.findViewById(R.id.notificationIcons);
-        mMoreIcon = (ImageView) statusBar.findViewById(R.id.moreIcon);
-        mNotificationIcons.setOverflowIndicator(mMoreIcon);
+
+        mNotificationIconAreaController =
+                new NotificationIconAreaController(context, phoneStatusBar);
+        mNotificationIconAreaInner =
+                mNotificationIconAreaController.getNotificationInnerAreaView();
+
+        ViewGroup notificationIconArea =
+                (ViewGroup) statusBar.findViewById(R.id.notification_icon_area);
+        notificationIconArea.addView(mNotificationIconAreaInner);
+
         mStatusIconsKeyguard = (LinearLayout) keyguardStatusBar.findViewById(R.id.statusIcons);
         mBatteryMeterView = (BatteryMeterView) statusBar.findViewById(R.id.battery);
         mClock = (TextView) statusBar.findViewById(R.id.clock);
@@ -259,60 +262,7 @@
     }
 
     public void updateNotificationIcons(NotificationData notificationData) {
-        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
-                mIconSize + 2*mIconHPadding, mPhoneStatusBar.getStatusBarHeight());
-
-        ArrayList<NotificationData.Entry> activeNotifications =
-                notificationData.getActiveNotifications();
-        final int N = activeNotifications.size();
-        ArrayList<StatusBarIconView> toShow = new ArrayList<>(N);
-
-        // Filter out ambient notifications and notification children.
-        for (int i = 0; i < N; i++) {
-            NotificationData.Entry ent = activeNotifications.get(i);
-            if (notificationData.isAmbient(ent.key)
-                    && !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
-                continue;
-            }
-            if (!PhoneStatusBar.isTopLevelChild(ent)) {
-                continue;
-            }
-            toShow.add(ent.icon);
-        }
-
-        ArrayList<View> toRemove = new ArrayList<>();
-        for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
-            View child = mNotificationIcons.getChildAt(i);
-            if (!toShow.contains(child)) {
-                toRemove.add(child);
-            }
-        }
-
-        final int toRemoveCount = toRemove.size();
-        for (int i = 0; i < toRemoveCount; i++) {
-            mNotificationIcons.removeView(toRemove.get(i));
-        }
-
-        for (int i=0; i<toShow.size(); i++) {
-            View v = toShow.get(i);
-            if (v.getParent() == null) {
-                mNotificationIcons.addView(v, i, params);
-            }
-        }
-
-        // Resort notification icons
-        final int childCount = mNotificationIcons.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View actual = mNotificationIcons.getChildAt(i);
-            StatusBarIconView expected = toShow.get(i);
-            if (actual == expected) {
-                continue;
-            }
-            mNotificationIcons.removeView(expected);
-            mNotificationIcons.addView(expected, i);
-        }
-
-        applyNotificationIconsTint();
+        mNotificationIconAreaController.updateNotificationIcons(notificationData);
     }
 
     public void hideSystemIconArea(boolean animate) {
@@ -324,11 +274,11 @@
     }
 
     public void hideNotificationIconArea(boolean animate) {
-        animateHide(mNotificationIconArea, animate);
+        animateHide(mNotificationIconAreaInner, animate);
     }
 
     public void showNotificationIconArea(boolean animate) {
-        animateShow(mNotificationIconArea, animate);
+        animateShow(mNotificationIconAreaInner, animate);
     }
 
     public void setClockVisibility(boolean visible) {
@@ -444,6 +394,7 @@
         mDarkIntensity = darkIntensity;
         mIconTint = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
                 mLightModeIconColorSingleTone, mDarkModeIconColorSingleTone);
+        mNotificationIconAreaController.setIconTint(mIconTint);
         applyIconTint();
     }
 
@@ -461,21 +412,8 @@
             v.setImageTintList(ColorStateList.valueOf(mIconTint));
         }
         mSignalCluster.setIconTint(mIconTint, mDarkIntensity);
-        mMoreIcon.setImageTintList(ColorStateList.valueOf(mIconTint));
         mBatteryMeterView.setDarkIntensity(mDarkIntensity);
         mClock.setTextColor(mIconTint);
-        applyNotificationIconsTint();
-    }
-
-    private void applyNotificationIconsTint() {
-        for (int i = 0; i < mNotificationIcons.getChildCount(); i++) {
-            StatusBarIconView v = (StatusBarIconView) mNotificationIcons.getChildAt(i);
-            boolean isPreL = Boolean.TRUE.equals(v.getTag(R.id.icon_is_pre_L));
-            boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mNotificationColorUtil);
-            if (colorize) {
-                v.setImageTintList(ColorStateList.valueOf(mIconTint));
-            }
-        }
     }
 
     public void appTransitionPending() {
@@ -512,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/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index f14f0d4..7a05b8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -30,6 +30,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.RemoteInputController;
 
@@ -54,11 +55,11 @@
 
     private static String TAG = "StatusBarKeyguardViewManager";
 
-    private final Context mContext;
+    protected final Context mContext;
 
-    private LockPatternUtils mLockPatternUtils;
-    private ViewMediatorCallback mViewMediatorCallback;
-    private PhoneStatusBar mPhoneStatusBar;
+    protected LockPatternUtils mLockPatternUtils;
+    protected ViewMediatorCallback mViewMediatorCallback;
+    protected PhoneStatusBar mPhoneStatusBar;
     private ScrimController mScrimController;
     private FingerprintUnlockController mFingerprintUnlockController;
 
@@ -67,17 +68,17 @@
 
     private boolean mDeviceInteractive = false;
     private boolean mScreenTurnedOn;
-    private KeyguardBouncer mBouncer;
-    private boolean mShowing;
-    private boolean mOccluded;
-    private boolean mRemoteInputActive;
+    protected KeyguardBouncer mBouncer;
+    protected boolean mShowing;
+    protected boolean mOccluded;
+    protected boolean mRemoteInputActive;
 
-    private boolean mFirstUpdate = true;
-    private boolean mLastShowing;
-    private boolean mLastOccluded;
+    protected boolean mFirstUpdate = true;
+    protected boolean mLastShowing;
+    protected boolean mLastOccluded;
     private boolean mLastBouncerShowing;
     private boolean mLastBouncerDismissible;
-    private boolean mLastRemoteInputActive;
+    protected boolean mLastRemoteInputActive;
 
     private OnDismissAction mAfterKeyguardGoneAction;
     private boolean mDeviceWillWakeUp;
@@ -99,8 +100,8 @@
         mStatusBarWindowManager = statusBarWindowManager;
         mScrimController = scrimController;
         mFingerprintUnlockController = fingerprintUnlockController;
-        mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils,
-                mStatusBarWindowManager, container);
+        mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
+                mViewMediatorCallback, mLockPatternUtils, mStatusBarWindowManager, container);
     }
 
     /**
@@ -118,7 +119,7 @@
      * Shows the notification keyguard or the bouncer depending on
      * {@link KeyguardBouncer#needsFullscreenBouncer()}.
      */
-    private void showBouncerOrKeyguard() {
+    protected void showBouncerOrKeyguard() {
         if (mBouncer.needsFullscreenBouncer()) {
 
             // The keyguard might be showing (already). So we need to hide it.
@@ -433,7 +434,7 @@
         }
     };
 
-    private void updateStates() {
+    protected void updateStates() {
         int vis = mContainer.getSystemUiVisibility();
         boolean showing = mShowing;
         boolean occluded = mOccluded;
@@ -451,9 +452,8 @@
             }
         }
 
-        boolean navBarVisible = (!(showing && !occluded) || bouncerShowing || remoteInputActive);
-        boolean lastNavBarVisible = (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing
-                || mLastRemoteInputActive);
+        boolean navBarVisible = isNavBarVisible();
+        boolean lastNavBarVisible = getLastNavBarVisible();
         if (navBarVisible != lastNavBarVisible || mFirstUpdate) {
             if (mPhoneStatusBar.getNavigationBarView() != null) {
                 if (navBarVisible) {
@@ -495,6 +495,20 @@
         mPhoneStatusBar.onKeyguardViewManagerStatesUpdated();
     }
 
+    /**
+     * @return Whether the navigation bar should be made visible based on the current state.
+     */
+    protected boolean isNavBarVisible() {
+        return !(mShowing && !mOccluded) || mBouncer.isShowing() || mRemoteInputActive;
+    }
+
+    /**
+     * @return Whether the navigation bar was made visible based on the last known state.
+     */
+    protected boolean getLastNavBarVisible() {
+        return !(mLastShowing && !mLastOccluded) || mLastBouncerShowing || mLastRemoteInputActive;
+    }
+
     public boolean onMenuPressed() {
         return mBouncer.onMenuPressed();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 9d2f0de..382de19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -134,6 +134,12 @@
             mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
             mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         }
+
+        if (state.remoteInputActive) {
+            mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
+        } else {
+            mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+        }
     }
 
     private void applyHeight(State state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
index 101a5f3..4f33d82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java
@@ -23,6 +23,9 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Shader;
@@ -41,6 +44,7 @@
     private float mFramePadding;
     private Bitmap mBitmap;
     private Drawable mDrawable;
+    private boolean mIsDisabled;
 
     private final Paint mFramePaint = new Paint();
     private final Paint mBitmapPaint = new Paint();
@@ -239,4 +243,28 @@
             mDrawable.setState(getDrawableState());
         }
     }
+
+    public void setDisabled(boolean disabled) {
+        if (mIsDisabled == disabled) {
+            return;
+        }
+        mIsDisabled = disabled;
+        int disabledColor = getContext().getColor(R.color.qs_tile_disabled_color);
+        PorterDuffColorFilter filter = new PorterDuffColorFilter(disabledColor,
+                PorterDuff.Mode.SRC_ATOP);
+        if (mBitmap != null) {
+            if (disabled) {
+                mBitmapPaint.setColorFilter(filter);
+            } else {
+                mBitmapPaint.setColorFilter(null);
+            }
+        } else if (mDrawable != null) {
+            if (disabled) {
+                mDrawable.setColorFilter(filter);
+            } else {
+                mDrawable.setColorFilter(null);
+            }
+        }
+        invalidate();
+    }
 }
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/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index b65bf43..ad8e3bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -440,6 +440,7 @@
                         + " dataState=" + state.getDataRegState());
             }
             mServiceState = state;
+            mDataNetType = state.getDataNetworkType();
             updateTelephony();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index f8c72b3..b2bcde3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.telephony.SubscriptionInfo;
-import com.android.settingslib.net.MobileDataController;
+import com.android.settingslib.net.DataUsageController;
 import com.android.settingslib.wifi.AccessPoint;
 
 import java.util.List;
@@ -32,7 +32,7 @@
     void setWifiEnabled(boolean enabled);
     void onUserSwitched(int newUserId);
     AccessPointController getAccessPointController();
-    MobileDataController getMobileDataController();
+    DataUsageController getMobileDataController();
 
     public interface SignalCallback {
         void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 909f497..3385c82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -40,7 +40,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.settingslib.net.MobileDataController;
+import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.DemoMode;
 import com.android.systemui.R;
 
@@ -59,7 +59,7 @@
 
 /** Platform implementation of the network controller. **/
 public class NetworkControllerImpl extends BroadcastReceiver
-        implements NetworkController, DemoMode, MobileDataController.NetworkNameProvider {
+        implements NetworkController, DemoMode, DataUsageController.NetworkNameProvider {
     // debug
     static final String TAG = "NetworkController";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -94,7 +94,7 @@
     // SIM for most actions.  This may be null if there aren't any SIMs around.
     private MobileSignalController mDefaultSignalController;
     private final AccessPointControllerImpl mAccessPoints;
-    private final MobileDataController mMobileDataController;
+    private final DataUsageController mDataUsageController;
 
     private boolean mInetCondition; // Used for Logging and demo.
 
@@ -139,7 +139,7 @@
                 SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
                 new CallbackHandler(),
                 new AccessPointControllerImpl(context, bgLooper),
-                new MobileDataController(context),
+                new DataUsageController(context),
                 new SubscriptionDefaults());
         mReceiverHandler.post(mRegisterListeners);
     }
@@ -150,7 +150,7 @@
             SubscriptionManager subManager, Config config, Looper bgLooper,
             CallbackHandler callbackHandler,
             AccessPointControllerImpl accessPointController,
-            MobileDataController mobileDataController,
+            DataUsageController dataUsageController,
             SubscriptionDefaults defaultsHandler) {
         mContext = context;
         mConfig = config;
@@ -171,10 +171,10 @@
 
         mLocale = mContext.getResources().getConfiguration().locale;
         mAccessPoints = accessPointController;
-        mMobileDataController = mobileDataController;
-        mMobileDataController.setNetworkController(this);
-        // TODO: Find a way to move this into MobileDataController.
-        mMobileDataController.setCallback(new MobileDataController.Callback() {
+        mDataUsageController = dataUsageController;
+        mDataUsageController.setNetworkController(this);
+        // TODO: Find a way to move this into DataUsageController.
+        mDataUsageController.setCallback(new DataUsageController.Callback() {
             @Override
             public void onMobileDataEnabled(boolean enabled) {
                 mCallbackHandler.setMobileDataEnabled(enabled);
@@ -236,8 +236,8 @@
     }
 
     @Override
-    public MobileDataController getMobileDataController() {
-        return mMobileDataController;
+    public DataUsageController getMobileDataController() {
+        return mDataUsageController;
     }
 
     public void addEmergencyListener(EmergencyListener listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 65053f3..61a9851 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -26,6 +26,7 @@
 import android.app.RemoteInput;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.text.Editable;
@@ -174,8 +175,8 @@
     }
 
     public void focus() {
-        mEditText.setInnerFocusable(true);
         mController.addRemoteInput(mEntry);
+        mEditText.setInnerFocusable(true);
         mEditText.mShowImeOnInputConnection = true;
         mEditText.setText(mEntry.remoteInputText);
         mEditText.setSelection(mEditText.getText().length());
@@ -257,6 +258,20 @@
         }
 
         @Override
+        public boolean requestRectangleOnScreen(Rect r) {
+            r.top = mScrollY;
+            r.bottom = mScrollY + (mBottom - mTop);
+            return super.requestRectangleOnScreen(r);
+        }
+
+        @Override
+        public void getFocusedRect(Rect r) {
+            super.getFocusedRect(r);
+            r.top = mScrollY;
+            r.bottom = mScrollY + (mBottom - mTop);
+        }
+
+        @Override
         public boolean onKeyPreIme(int keyCode, KeyEvent event) {
             if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
                 defocusIfNeeded();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index f3a3554..05d9626 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -22,7 +22,9 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -33,6 +35,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -48,11 +51,13 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.UserIcons;
+import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.BitmapHelper;
 import com.android.systemui.GuestResumeSessionReceiver;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.tiles.UserDetailView;
+import com.android.systemui.statusbar.phone.ActivityStarter;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 import java.io.FileDescriptor;
@@ -61,6 +66,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
 /**
  * Keeps a list of all users on the device for user switching.
  */
@@ -88,6 +95,7 @@
             = new GuestResumeSessionReceiver();
     private final KeyguardMonitor mKeyguardMonitor;
     private final Handler mHandler;
+    private final ActivityStarter mActivityStarter;
 
     private ArrayList<UserRecord> mUsers = new ArrayList<>();
     private Dialog mExitGuestDialog;
@@ -99,11 +107,12 @@
     private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
 
     public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor,
-            Handler handler) {
+            Handler handler, ActivityStarter activityStarter) {
         mContext = context;
         mGuestResumeSessionReceiver.register(context);
         mKeyguardMonitor = keyguardMonitor;
         mHandler = handler;
+        mActivityStarter = activityStarter;
         mUserManager = UserManager.get(context);
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_ADDED);
@@ -206,25 +215,23 @@
                     }
                 }
 
-                boolean systemCanCreateUsers = !mUserManager.hasUserRestriction(
-                                UserManager.DISALLOW_ADD_USER, UserHandle.SYSTEM);
                 boolean currentUserCanCreateUsers = currentUserInfo != null
                         && (currentUserInfo.isAdmin()
-                                || currentUserInfo.id == UserHandle.USER_SYSTEM)
-                        && systemCanCreateUsers;
-                boolean anyoneCanCreateUsers = systemCanCreateUsers && addUsersWhenLocked;
-                boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers)
+                                || currentUserInfo.id == UserHandle.USER_SYSTEM);
+                boolean canCreateGuest = (currentUserCanCreateUsers || addUsersWhenLocked)
                         && guestRecord == null;
-                boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers)
+                boolean canCreateUser = (currentUserCanCreateUsers || addUsersWhenLocked)
                         && mUserManager.canAddMoreUsers();
                 boolean createIsRestricted = !addUsersWhenLocked;
 
                 if (!mSimpleUserSwitcher) {
                     if (guestRecord == null) {
                         if (canCreateGuest) {
-                            records.add(new UserRecord(null /* info */, null /* picture */,
+                            guestRecord = new UserRecord(null /* info */, null /* picture */,
                                     true /* isGuest */, false /* isCurrent */,
-                                    false /* isAddUser */, createIsRestricted));
+                                    false /* isAddUser */, createIsRestricted);
+                            checkIfAddUserDisallowed(guestRecord);
+                            records.add(guestRecord);
                         }
                     } else {
                         int index = guestRecord.isCurrent ? 0 : records.size();
@@ -233,9 +240,11 @@
                 }
 
                 if (!mSimpleUserSwitcher && canCreateUser) {
-                    records.add(new UserRecord(null /* info */, null /* picture */,
+                    UserRecord addUserRecord = new UserRecord(null /* info */, null /* picture */,
                             false /* isGuest */, false /* isCurrent */, true /* isAddUser */,
-                            createIsRestricted));
+                            createIsRestricted);
+                    checkIfAddUserDisallowed(addUserRecord);
+                    records.add(addUserRecord);
                 }
 
                 return records;
@@ -289,6 +298,14 @@
         return mContext.getResources().getBoolean(R.bool.config_enableFullscreenUserSwitcher);
     }
 
+    public void logoutCurrentUser() {
+        int currentUser = ActivityManager.getCurrentUser();
+        if (currentUser != UserHandle.USER_SYSTEM) {
+            switchToUserId(UserHandle.USER_SYSTEM);
+            stopUserId(currentUser);
+        }
+    }
+
     public void removeUserId(int userId) {
         if (userId == UserHandle.USER_SYSTEM) {
             Log.w(TAG, "User " + userId + " could not removed.");
@@ -331,6 +348,19 @@
         switchToUserId(id);
     }
 
+    public void switchTo(int userId) {
+        final int count = mUsers.size();
+        for (int i = 0; i < count; ++i) {
+            UserRecord record = mUsers.get(i);
+            if (record.info != null && record.info.id == userId) {
+                switchTo(record);
+                return;
+            }
+        }
+
+        Log.e(TAG, "Couldn't switch to user, id=" + userId);
+    }
+
     private void switchToUserId(int id) {
         try {
             pauseRefreshUsers();
@@ -395,11 +425,7 @@
                 }
                 return;
             } else if (ACTION_LOGOUT_USER.equals(intent.getAction())) {
-                int currentUser = ActivityManager.getCurrentUser();
-                if (currentUser != UserHandle.USER_SYSTEM) {
-                    switchToUserId(UserHandle.USER_SYSTEM);
-                    stopUserId(currentUser);
-                }
+                logoutCurrentUser();
             } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
                 if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
                     mExitGuestDialog.cancel();
@@ -594,6 +620,22 @@
         }
     }
 
+    private void checkIfAddUserDisallowed(UserRecord record) {
+        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
+        if (admin != null) {
+            record.isDisabledByAdmin = true;
+            record.enforcedAdmin = admin;
+        } else {
+            record.isDisabledByAdmin = false;
+            record.enforcedAdmin = null;
+        }
+    }
+
+    public void startActivity(Intent intent) {
+        mActivityStarter.startActivity(intent, true);
+    }
+
     public static final class UserRecord {
         public final UserInfo info;
         public final Bitmap picture;
@@ -602,6 +644,8 @@
         public final boolean isAddUser;
         /** If true, the record is only visible to the owner and only when unlocked. */
         public final boolean isRestricted;
+        public boolean isDisabledByAdmin;
+        public EnforcedAdmin enforcedAdmin;
 
         public UserRecord(UserInfo info, Bitmap picture, boolean isGuest, boolean isCurrent,
                 boolean isAddUser, boolean isRestricted) {
@@ -634,6 +678,10 @@
             if (isCurrent) sb.append(" <isCurrent>");
             if (picture != null) sb.append(" <hasPicture>");
             if (isRestricted) sb.append(" <isRestricted>");
+            if (isDisabledByAdmin) {
+                sb.append(" <isDisabledByAdmin>");
+                sb.append(" enforcedAdmin=" + enforcedAdmin);
+            }
             sb.append(')');
             return sb.toString();
         }
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
new file mode 100644
index 0000000..3d91d62
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.tv.pip;
+
+import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
+import android.app.IActivityManager;
+import android.app.ITaskStackListener;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.
+ */
+public class PipManager {
+    private static final String TAG = "PipManager";
+    private static final boolean DEBUG = false;
+
+    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;
+    private final Handler mHandler = new Handler();
+    private List<Listener> mListeners = new ArrayList<>();
+    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() {
+            StackInfo stackInfo = null;
+            try {
+                stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+                if (stackInfo == null) {
+                    Log.w(TAG, "There is no pinned stack");
+                    return;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "getStackInfo failed", e);
+                return;
+            }
+            if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
+            mState = STATE_PIP_OVERLAY;
+            mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
+            launchPipOverlayActivity();
+        }
+    };
+    private final Runnable mOnTaskStackChanged = new Runnable() {
+        @Override
+        public void run() {
+            if (mState != STATE_NO_PIP) {
+                // TODO: check whether PIP task is closed.
+            }
+        }
+    };
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            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);
+                }
+            }
+
+        }
+    };
+
+    private PipManager() { }
+
+    /**
+     * Initializes {@link PipManager}.
+     */
+    public void initialize(Context context) {
+        if (mInitialized) {
+            return;
+        }
+        mInitialized = true;
+        mContext = context;
+        Resources res = context.getResources();
+        mPipBound = Rect.unflattenFromString(res.getString(
+                com.android.internal.R.string.config_defaultPictureInPictureBounds));
+        mMenuModePipBound = Rect.unflattenFromString(res.getString(
+                com.android.internal.R.string.config_centeredPictureInPictureBounds));
+
+        mActivityManager = ActivityManagerNative.getDefault();
+        TaskStackListener taskStackListener = new TaskStackListener();
+        IActivityManager iam = ActivityManagerNative.getDefault();
+        try {
+            iam.registerTaskStackListener(taskStackListener);
+        } catch (RemoteException e) {
+            Log.e(TAG, "registerTaskStackListener failed", e);
+        }
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_PICTURE_IN_PICTURE_BUTTON);
+        intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+    }
+
+    private void startPip() {
+        try {
+            mActivityManager.moveTopActivityToPinnedStack(FULLSCREEN_WORKSPACE_STACK_ID, mPipBound);
+        } catch (RemoteException|IllegalArgumentException e) {
+            Log.e(TAG, "moveTopActivityToPinnedStack failed", e);
+        }
+
+    }
+
+    /**
+     * Closes PIP (PIPped activity and PIP system UI).
+     */
+    public void closePip() {
+        mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
+        StackInfo stackInfo = null;
+        try {
+            stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+            if (stackInfo == null) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "getStackInfo failed", e);
+            return;
+        }
+        for (int taskId : stackInfo.taskIds) {
+            try {
+                mActivityManager.removeTask(taskId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "removeTask failed", e);
+            }
+        }
+    }
+
+    /**
+     * Moves the PIPped activity to the fullscreen and closes PIP system UI.
+     */
+    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();
+        }
+        try {
+            mActivityManager.moveTasksToFullscreenStack(PINNED_STACK_ID, true);
+        } catch (RemoteException e) {
+            Log.e(TAG, "moveTasksToFullscreenStack failed", e);
+        }
+    }
+
+    /**
+     * Shows PIP overlay UI by launching {@link PipOverlayActivity}. It also locates the pinned
+     * stack to the default PIP bound {@link com.android.internal.R.string
+     * .config_defaultPictureInPictureBounds}.
+     */
+    public void showPipOverlay() {
+        if (DEBUG) Log.d(TAG, "showPipOverlay()");
+        try {
+            mActivityManager.resizeStack(PINNED_STACK_ID, mPipBound, false);
+        } catch (Exception e) {
+            Log.e(TAG, "resizeStack failed", e);
+            closePip();
+            return;
+        }
+        mState = STATE_PIP_OVERLAY;
+        launchPipOverlayActivity();
+    }
+
+    /**
+     * Shows PIP menu UI by launching {@link PipMenuActivity}. It also locates the pinned
+     * stack to the centered PIP bound {@link com.android.internal.R.string
+     * .config_centeredPictureInPictureBounds}.
+     */
+    public void showPipMenu() {
+        if (DEBUG) Log.d(TAG, "showPipMenu()");
+        try {
+            mActivityManager.resizeStack(PINNED_STACK_ID, mMenuModePipBound, false);
+        } catch (Exception e) {
+            Log.e(TAG, "resizeStack failed", e);
+            closePip();
+            return;
+        }
+        mState = STATE_PIP_MENU;
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onShowPipMenu();
+        }
+        Intent intent = new Intent(mContext, PipMenuActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchStackId(PINNED_STACK_ID);
+        mContext.startActivity(intent, options.toBundle());
+    }
+
+    /**
+     * Adds {@link Listener}.
+     */
+    public void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    /**
+     * Removes {@link Listener}.
+     */
+    public void removeListener(Listener listener) {
+        mListeners.remove(listener);
+    }
+
+    private void launchPipOverlayActivity() {
+        Intent intent = new Intent(mContext, PipOverlayActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchStackId(PINNED_STACK_ID);
+        mContext.startActivity(intent, options.toBundle());
+    }
+
+    private boolean hasPipTasks() {
+        try {
+            StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+            return stackInfo != null;
+        } catch (RemoteException e) {
+            Log.e(TAG, "getStackInfo failed", e);
+            return false;
+        }
+    }
+
+    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 {
+            // Post the message back to the UI thread.
+            mHandler.post(mOnTaskStackChanged);
+        }
+
+        @Override
+        public void onActivityPinned()  throws RemoteException {
+            // Post the message back to the UI thread.
+            mHandler.post(mOnActivityPinnedRunnable);
+        }
+    }
+
+    /**
+     * A listener interface to receive notification on changes in PIP.
+     */
+    public interface Listener {
+        /**
+         * Invoked when a PIPped activity is closed.
+         */
+        void onPipActivityClosed();
+        /**
+         * Invoked when the PIP menu gets shown.
+         */
+        void onShowPipMenu();
+        /**
+         * Invoked when the PIPped activity is returned back to the fullscreen.
+         */
+        void onMoveToFullscreen();
+    }
+
+    /**
+     * Gets an instance of {@link PipManager}.
+     */
+    public static PipManager getInstance() {
+        if (sPipManager == null) {
+            sPipManager = new PipManager();
+        }
+        return sPipManager;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
new file mode 100644
index 0000000..1248321
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.tv.pip;
+
+import android.app.Activity;
+import android.media.session.MediaController;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.R;
+
+/**
+ * Activity to show the PIP menu to control PIP.
+ */
+public class PipMenuActivity extends Activity implements PipManager.Listener {
+    private static final String TAG = "PipMenuActivity";
+    private static final boolean DEBUG = false;
+
+    private final PipManager mPipManager = PipManager.getInstance();
+    private MediaController mMediaController;
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        setContentView(R.layout.tv_pip_menu);
+        mPipManager.addListener(this);
+        findViewById(R.id.full).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mPipManager.movePipToFullscreen();
+            }
+        });
+        findViewById(R.id.exit).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mPipManager.closePip();
+                finish();
+            }
+        });
+        findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mPipManager.showPipOverlay();
+                finish();
+            }
+        });
+    }
+
+    @Override
+    protected void onDestroy() {
+        mPipManager.removeListener(this);
+        super.onDestroy();
+    }
+
+    @Override
+    public void onBackPressed() {
+        mPipManager.showPipOverlay();
+        finish();
+    }
+
+    @Override
+    public void onPipActivityClosed() {
+        finish();
+    }
+
+    @Override
+    public void onShowPipMenu() { }
+
+    @Override
+    public void onMoveToFullscreen() {
+        finish();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
new file mode 100644
index 0000000..de997a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.tv.pip;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.R;
+
+/**
+ * Activity to show an overlay on top of PIP activity to show how to pop up PIP menu.
+ */
+public class PipOverlayActivity extends Activity implements PipManager.Listener {
+    private static final String TAG = "PipOverlayActivity";
+    private static final boolean DEBUG = false;
+
+    private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 2000;
+
+    private final PipManager mPipManager = PipManager.getInstance();
+    private final Handler mHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        setContentView(R.layout.tv_pip_overlay);
+        mPipManager.addListener(this);
+        final View overlayView = findViewById(R.id.guide_overlay);
+        // TODO: apply animation
+        overlayView.setVisibility(View.VISIBLE);
+        mHandler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                overlayView.setVisibility(View.INVISIBLE);
+            }
+        }, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mHandler.removeCallbacksAndMessages(null);
+        mPipManager.removeListener(this);
+    }
+
+    @Override
+    public void onPipActivityClosed() {
+        finish();
+    }
+
+    @Override
+    public void onShowPipMenu() {
+        finish();
+    }
+
+    @Override
+    public void onMoveToFullscreen() {
+        finish();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipUI.java
new file mode 100644
index 0000000..182b9b0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipUI.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.tv.pip;
+
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+
+import com.android.systemui.SystemUI;
+
+import static android.content.pm.PackageManager.FEATURE_LEANBACK;
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+
+/**
+ * Controls the picture-in-picture window for TV devices.
+ */
+public class PipUI extends SystemUI {
+    private boolean mSupportPip;
+
+    @Override
+    public void start() {
+        PackageManager pm = mContext.getPackageManager();
+        mSupportPip = pm.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)
+                && pm.hasSystemFeature(FEATURE_LEANBACK);
+        if (!mSupportPip) {
+            return;
+        }
+        PipManager pipManager = PipManager.getInstance();
+        pipManager.initialize(mContext);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (!mSupportPip) {
+            return;
+        }
+        // TODO: handle configuration change.
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 0901015..ed6fc9e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -21,7 +21,6 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.animation.LayoutTransition;
-import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.SuppressLint;
 import android.app.Dialog;
@@ -62,7 +61,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-import android.view.animation.DecelerateInterpolator;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.SeekBar;
@@ -71,6 +69,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.tuner.TunerService;
 import com.android.systemui.volume.VolumeDialogController.State;
 import com.android.systemui.volume.VolumeDialogController.StreamState;
 
@@ -85,9 +84,11 @@
  *
  * Methods ending in "H" must be called on the (ui) handler.
  */
-public class VolumeDialog {
+public class VolumeDialog implements TunerService.Tunable {
     private static final String TAG = Util.logTag(VolumeDialog.class);
 
+    public static final String SHOW_FULL_ZEN = "sysui_show_full_zen";
+
     private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
     private static final int WAIT_FOR_RIPPLE = 200;
 
@@ -131,6 +132,9 @@
     private boolean mHovering = false;
     private int mLastActiveStream;
 
+    private boolean mShowFullZen;
+    private final ZenModePanel mZenPanel;
+
     public VolumeDialog(Context context, int windowType, VolumeDialogController controller,
             ZenModeController zenModeController, Callback callback) {
         mContext = context;
@@ -221,11 +225,23 @@
         mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
         mZenFooter = (ZenFooter) mDialog.findViewById(R.id.volume_zen_footer);
         mZenFooter.init(zenModeController);
+        mZenPanel = (ZenModePanel) mDialog.findViewById(R.id.zen_mode_panel);
+        mZenPanel.addNoneButton();
+        mZenPanel.init(zenModeController);
+        mZenPanel.setCallback(mZenPanelCallback);
 
         mAccessibility.init();
 
         controller.addCallback(mControllerCallbackH, mHandler);
         controller.getState();
+        TunerService.get(mContext).addTunable(this, SHOW_FULL_ZEN);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (SHOW_FULL_ZEN.equals(key)) {
+            mShowFullZen = newValue != null && Integer.parseInt(newValue) != 0;
+        }
     }
 
     private ColorStateList loadColorStateList(int colorResId) {
@@ -278,7 +294,7 @@
                     .getDimensionPixelSize(R.dimen.volume_slider_interspacing);
             final LinearLayout.LayoutParams lp =
                     new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, h);
-            mDialogContentView.addView(v, mDialogContentView.getChildCount() - 1, lp);
+            mDialogContentView.addView(v, mDialogContentView.getChildCount() - 2, lp);
             row.space = v;
         }
         row.settingsButton.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@@ -306,7 +322,7 @@
             }
         });
         // add new row just before the footer
-        mDialogContentView.addView(row.view, mDialogContentView.getChildCount() - 1);
+        mDialogContentView.addView(row.view, mDialogContentView.getChildCount() - 2);
         mRows.add(row);
     }
 
@@ -655,12 +671,21 @@
         if (D.BUG) Log.d(TAG, "updateFooterH");
         final boolean wasVisible = mZenFooter.getVisibility() == View.VISIBLE;
         final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF
-                && (mAudioManager.isStreamAffectedByRingerMode(mActiveStream) || mExpanded);
+                && (mAudioManager.isStreamAffectedByRingerMode(mActiveStream) || mExpanded)
+                && !mShowFullZen;
         if (wasVisible != visible && !visible) {
             prepareForCollapse();
         }
         Util.setVisOrGone(mZenFooter, visible);
         mZenFooter.update();
+
+        final boolean fullWasVisible = mZenPanel.getVisibility() == View.VISIBLE;
+        final boolean fullVisible = mShowFullZen && (mState.zenMode != Global.ZEN_MODE_OFF
+                || mExpanded);
+        if (fullWasVisible != fullVisible && !fullVisible) {
+            prepareForCollapse();
+        }
+        Util.setVisOrGone(mZenPanel, fullVisible);
     }
 
     private void updateVolumeRowH(VolumeRow row) {
@@ -903,6 +928,23 @@
         }
     };
 
+    private final ZenModePanel.Callback mZenPanelCallback = new ZenModePanel.Callback() {
+        @Override
+        public void onPrioritySettings() {
+            mCallback.onZenPrioritySettingsClicked();
+        }
+
+        @Override
+        public void onInteraction() {
+            mHandler.sendEmptyMessage(H.RESCHEDULE_TIMEOUT);
+        }
+
+        @Override
+        public void onExpanded(boolean expanded) {
+            // noop.
+        }
+    };
+
     private final OnClickListener mClickExpand = new OnClickListener() {
         @Override
         public void onClick(View v) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 1083f40..d7635ad 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -31,6 +31,7 @@
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.tuner.TunerService;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -38,16 +39,25 @@
 /**
  * Implementation of VolumeComponent backed by the new volume dialog.
  */
-public class VolumeDialogComponent implements VolumeComponent {
+public class VolumeDialogComponent implements VolumeComponent, TunerService.Tunable {
+
+    public static final String VOLUME_DOWN_SILENT = "sysui_volume_down_silent";
+    public static final String VOLUME_UP_SILENT = "sysui_volume_up_silent";
+    public static final String VOLUME_SILENT_DO_NOT_DISTURB = "sysui_do_not_disturb";
+
+    public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = true;
+    public static final boolean DEFAULT_VOLUME_UP_TO_EXIT_SILENT = true;
+    public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = true;
+
     private final SystemUI mSysui;
     private final Context mContext;
     private final VolumeDialogController mController;
     private final ZenModeController mZenModeController;
     private final VolumeDialog mDialog;
-    private final VolumePolicy mVolumePolicy = new VolumePolicy(
-            true,  // volumeDownToEnterSilent
-            true,  // volumeUpToExitSilent
-            true,  // doNotDisturbWhenSilent
+    private VolumePolicy mVolumePolicy = new VolumePolicy(
+            DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT,  // volumeDownToEnterSilent
+            DEFAULT_VOLUME_UP_TO_EXIT_SILENT,  // volumeUpToExitSilent
+            DEFAULT_DO_NOT_DISTURB_WHEN_SILENT,  // doNotDisturbWhenSilent
             400    // vibrateToSilentDebounce
     );
 
@@ -65,6 +75,41 @@
         mDialog = new VolumeDialog(context, WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY,
                 mController, zen, mVolumeDialogCallback);
         applyConfiguration();
+        TunerService.get(mContext).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
+                VOLUME_SILENT_DO_NOT_DISTURB);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (VOLUME_DOWN_SILENT.equals(key)) {
+            final boolean volumeDownToEnterSilent = newValue != null
+                    ? Integer.parseInt(newValue) != 0
+                    : DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT;
+            setVolumePolicy(volumeDownToEnterSilent,
+                    mVolumePolicy.volumeUpToExitSilent, mVolumePolicy.doNotDisturbWhenSilent,
+                    mVolumePolicy.vibrateToSilentDebounce);
+        } else if (VOLUME_UP_SILENT.equals(key)) {
+            final boolean volumeUpToExitSilent = newValue != null
+                    ? Integer.parseInt(newValue) != 0
+                    : DEFAULT_VOLUME_UP_TO_EXIT_SILENT;
+            setVolumePolicy(mVolumePolicy.volumeDownToEnterSilent,
+                    volumeUpToExitSilent, mVolumePolicy.doNotDisturbWhenSilent,
+                    mVolumePolicy.vibrateToSilentDebounce);
+        } else if (VOLUME_SILENT_DO_NOT_DISTURB.equals(key)) {
+            final boolean doNotDisturbWhenSilent = newValue != null
+                    ? Integer.parseInt(newValue) != 0
+                    : DEFAULT_DO_NOT_DISTURB_WHEN_SILENT;
+            setVolumePolicy(mVolumePolicy.volumeDownToEnterSilent,
+                    mVolumePolicy.volumeUpToExitSilent, doNotDisturbWhenSilent,
+                    mVolumePolicy.vibrateToSilentDebounce);
+        }
+    }
+
+    private void setVolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent,
+            boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce) {
+        mVolumePolicy = new VolumePolicy(volumeDownToEnterSilent, volumeUpToExitSilent,
+                doNotDisturbWhenSilent, vibrateToSilentDebounce);
+        mController.setVolumePolicy(mVolumePolicy);
     }
 
     private void sendUserActivity() {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 38d8de0..f73ba6f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -189,6 +189,12 @@
         mZenAlarmWarning = (TextView) findViewById(R.id.zen_alarm_warning);
     }
 
+    public void addNoneButton() {
+        mZenButtons.addButton(R.string.interruption_level_all_twoline,
+                R.string.interruption_level_all,
+                Global.ZEN_MODE_OFF);
+    }
+
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
@@ -494,6 +500,7 @@
         if (mExpanded && isShown()) {
             ensureSelection();
         }
+        mZenConditions.setVisibility(mSessionZen != Global.ZEN_MODE_OFF ? View.VISIBLE : View.GONE);
     }
 
     private Condition forever() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
index 6ebf488..f86c6a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java
@@ -283,6 +283,11 @@
                 public void onClick(IBinder iBinder) throws RemoteException {
                     sendCallback("onClick");
                 }
+
+                @Override
+                public void onUnlockComplete() throws RemoteException {
+                    sendCallback("onUnlockComplete");
+                }
             };
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 13fc47d..5cf3767 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -33,7 +33,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.cdma.EriInfo;
-import com.android.settingslib.net.MobileDataController;
+import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
@@ -60,8 +60,8 @@
     protected NetworkControllerImpl mNetworkController;
     protected MobileSignalController mMobileSignalController;
     protected PhoneStateListener mPhoneStateListener;
-    private SignalStrength mSignalStrength;
-    private ServiceState mServiceState;
+    protected SignalStrength mSignalStrength;
+    protected ServiceState mServiceState;
     protected ConnectivityManager mMockCm;
     protected WifiManager mMockWm;
     protected SubscriptionManager mMockSm;
@@ -96,7 +96,7 @@
         mCallbackHandler = mock(CallbackHandler.class);
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataController.class),
+                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults);
         setupNetworkController();
 
@@ -137,7 +137,7 @@
               = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                         mConfig, Looper.getMainLooper(), mCallbackHandler,
                         mock(AccessPointControllerImpl.class),
-                        mock(MobileDataController.class), mMockSubDefaults);
+                        mock(DataUsageController.class), mMockSubDefaults);
 
       setupNetworkController();
 
@@ -235,7 +235,7 @@
         mPhoneStateListener.onSignalStrengthsChanged(mSignalStrength);
     }
 
-    private void updateServiceState() {
+    protected void updateServiceState() {
         Log.d(TAG, "Sending Service State: " + mServiceState);
         mPhoneStateListener.onServiceStateChanged(mServiceState);
     }
@@ -246,6 +246,7 @@
     }
 
     public void updateDataConnectionState(int dataState, int dataNetType) {
+        when(mServiceState.getDataNetworkType()).thenReturn(dataNetType);
         mPhoneStateListener.onDataConnectionStateChanged(dataState, dataNetType);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 587e2b5..d5eca95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -4,7 +4,7 @@
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.settingslib.net.MobileDataController;
+import com.android.settingslib.net.DataUsageController;
 import org.mockito.Mockito;
 
 @SmallTest
@@ -88,7 +88,7 @@
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 Mockito.mock(AccessPointControllerImpl.class),
-                Mockito.mock(MobileDataController.class), mMockSubDefaults);
+                Mockito.mock(DataUsageController.class), mMockSubDefaults);
         setupNetworkController();
 
         setupDefaultSignal();
@@ -115,6 +115,21 @@
                 TelephonyIcons.QS_DATA_4G);
     }
 
+    public void testDataChangeWithoutConnectionState() {
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        verifyDataIndicators(TelephonyIcons.DATA_LTE[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_LTE);
+
+        Mockito.when(mServiceState.getDataNetworkType())
+                .thenReturn(TelephonyManager.NETWORK_TYPE_HSPA);
+        updateServiceState();
+        verifyDataIndicators(TelephonyIcons.DATA_H[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_H);
+    }
+
     public void testDataActivity() {
         setupDefaultSignal();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 760aa9a..08da382 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -29,7 +29,7 @@
 
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.settingslib.net.MobileDataController;
+import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.R;
 
 import org.mockito.ArgumentCaptor;
@@ -47,7 +47,7 @@
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataController.class),
+                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults);
         setupNetworkController();
 
@@ -96,7 +96,7 @@
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataController.class),
+                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults);
         setupNetworkController();
 
diff --git a/packages/VpnDialogs/res/values-de/strings.xml b/packages/VpnDialogs/res/values-de/strings.xml
index 168937b..27b0196 100644
--- a/packages/VpnDialogs/res/values-de/strings.xml
+++ b/packages/VpnDialogs/res/values-de/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"Verbindungsanfrage"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> möchte eine VPN-Verbindung herstellen, über die der Netzwerkverkehr überwacht werden kann. Lassen Sie die Verbindung nur zu, wenn die App vertrauenswürdig ist. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; wird oben am Display angezeigt, wenn VPN aktiv ist."</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> möchte eine VPN-Verbindung herstellen, über die der Netzwerkverkehr überwacht werden kann. Lasse die Verbindung nur zu, wenn die App vertrauenswürdig ist. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; wird oben am Display angezeigt, wenn VPN aktiv ist."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN ist verbunden"</string>
     <string name="configure" msgid="4905518375574791375">"Konfigurieren"</string>
     <string name="disconnect" msgid="971412338304200056">"Verbindung trennen"</string>
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 39d5952..dbbb189 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -715,7 +715,7 @@
     }
 
     @Override
-    public IBinder getWindowToken(int windowId) {
+    public IBinder getWindowToken(int windowId, int userId) {
         mSecurityPolicy.enforceCallingPermission(
                 Manifest.permission.RETRIEVE_WINDOW_TOKEN,
                 GET_WINDOW_TOKEN);
@@ -724,8 +724,7 @@
             // share the accessibility state of the parent. The call below
             // performs the current profile parent resolution.
             final int resolvedUserId = mSecurityPolicy
-                    .resolveCallingUserIdEnforcingPermissionsLocked(
-                            UserHandle.getCallingUserId());
+                    .resolveCallingUserIdEnforcingPermissionsLocked(userId);
             if (resolvedUserId != mCurrentUserId) {
                 return null;
             }
@@ -2180,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 2264c69..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;
@@ -239,6 +243,11 @@
     // How long between attempts to perform a full-data backup of any given app
     static final long MIN_FULL_BACKUP_INTERVAL = 1000 * 60 * 60 * 24; // one day
 
+    // If an app is busy when we want to do a full-data backup, how long to defer the retry.
+    // This is fuzzed, so there are two parameters; backoff_min + Rand[0, backoff_fuzz)
+    static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60;  // one hour
+    static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2;  // two hours
+
     Context mContext;
     private PackageManager mPackageManager;
     IPackageManager mPackageManagerBinder;
@@ -527,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;
@@ -714,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) {
@@ -937,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;
+            }
             }
         }
     }
@@ -2325,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
 
@@ -2424,6 +2529,8 @@
         File mStateDir;
         File mJournal;
         BackupState mCurrentState;
+        ArrayList<String> mPendingFullBackups;
+        IBackupObserver mObserver;
 
         // carried information about the current in-flight operation
         IBackupAgent mAgentBinder;
@@ -2436,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);
 
@@ -2493,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;
             }
@@ -2579,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);
                 }
             }
@@ -2620,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;
                 }
@@ -2631,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;
                 }
@@ -2640,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;
                 }
@@ -2687,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();
@@ -2745,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();
         }
 
@@ -2954,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;
@@ -2998,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
@@ -3025,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) {
@@ -3032,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;
@@ -3285,6 +3450,8 @@
          *         or one of the other BackupTransport.* error codes as appropriate
          */
         int preflightFullBackup(PackageInfo pkg, IBackupAgent agent);
+
+        long expectedSize();
     };
 
     class FullBackupEngine {
@@ -3992,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 {
@@ -4015,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)) {
@@ -4023,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
@@ -4031,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);
@@ -4063,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) {
@@ -4086,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
@@ -4114,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()) {
@@ -4130,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);
 
@@ -4183,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);
@@ -4202,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);
@@ -4216,6 +4417,7 @@
                     mRunningFullBackupTask = null;
                 }
 
+
                 mLatch.countDown();
 
                 // Now that we're actually done with schedule-driven work, reschedule
@@ -4223,6 +4425,8 @@
                 if (mUpdateSchedule) {
                     scheduleNextFullBackupJob(backoff);
                 }
+                Slog.i(BackupManagerService.TAG, "Full data backup pass finished.");
+                mWakelock.release();
             }
         }
 
@@ -4311,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 {
@@ -4346,6 +4559,10 @@
                     }
                 }
             }
+
+            long expectedSize() {
+                return mPreflight.expectedSize();
+            }
         }
     }
 
@@ -4496,35 +4713,72 @@
                 return false;
             }
 
-            // At this point we know that we have work to do, just not right now.  Any
-            // exit without actually running backups will also require that we
+            // At this point we know that we have work to do, but possibly not right now.
+            // Any exit without actually running backups will also require that we
             // reschedule the job.
             boolean runBackup = true;
+            boolean headBusy;
 
-            if (!fullBackupAllowable(getTransport(mCurrentTransport))) {
-                if (MORE_DEBUG) {
-                    Slog.i(TAG, "Preconditions not met; not running full backup");
-                }
-                runBackup = false;
-                // Typically this means we haven't run a key/value backup yet.  Back off
-                // full-backup operations by the key/value job's run interval so that
-                // next time we run, we are likely to be able to make progress.
-                latency = KeyValueBackupJob.BATCH_INTERVAL;
-            }
+            do {
+                headBusy = false;
 
-            if (runBackup) {
-                entry = mFullBackupQueue.get(0);
-                long timeSinceRun = now - entry.lastBackup;
-                runBackup = (timeSinceRun >= MIN_FULL_BACKUP_INTERVAL);
-                if (!runBackup) {
-                    // It's too early to back up the next thing in the queue, so bow out
+                if (!fullBackupAllowable(getTransport(mCurrentTransport))) {
                     if (MORE_DEBUG) {
-                        Slog.i(TAG, "Device ready but too early to back up next app");
+                        Slog.i(TAG, "Preconditions not met; not running full backup");
                     }
-                    // Wait until the next app in the queue falls due for a full data backup
-                    latency = MIN_FULL_BACKUP_INTERVAL - timeSinceRun;
+                    runBackup = false;
+                    // Typically this means we haven't run a key/value backup yet.  Back off
+                    // full-backup operations by the key/value job's run interval so that
+                    // next time we run, we are likely to be able to make progress.
+                    latency = KeyValueBackupJob.BATCH_INTERVAL;
                 }
-            }
+
+                if (runBackup) {
+                    entry = mFullBackupQueue.get(0);
+                    long timeSinceRun = now - entry.lastBackup;
+                    runBackup = (timeSinceRun >= MIN_FULL_BACKUP_INTERVAL);
+                    if (!runBackup) {
+                        // It's too early to back up the next thing in the queue, so bow out
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Device ready but too early to back up next app");
+                        }
+                        // Wait until the next app in the queue falls due for a full data backup
+                        latency = MIN_FULL_BACKUP_INTERVAL - timeSinceRun;
+                        break;  // we know we aren't doing work yet, so bail.
+                    }
+
+                    try {
+                        PackageInfo appInfo = mPackageManager.getPackageInfo(entry.packageName, 0);
+                        headBusy = mActivityManager.isAppForeground(appInfo.applicationInfo.uid);
+
+                        if (headBusy) {
+                            final long nextEligible = System.currentTimeMillis()
+                                    + BUSY_BACKOFF_MIN_MILLIS
+                                    + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ);
+                            if (DEBUG_SCHEDULING) {
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                Slog.i(TAG, "Full backup time but " + entry.packageName
+                                        + " is busy; deferring to "
+                                        + sdf.format(new Date(nextEligible)));
+                            }
+                            // This relocates the app's entry from the head of the queue to
+                            // its order-appropriate position further down, so upon looping
+                            // a new candidate will be considered at the head.
+                            enqueueFullBackup(entry.packageName,
+                                    nextEligible - MIN_FULL_BACKUP_INTERVAL);
+                        }
+
+                    } catch (NameNotFoundException nnf) {
+                        // So, we think we want to back this up, but it turns out the package
+                        // in question is no longer installed.  We want to drop it from the
+                        // queue entirely and move on, but if there's nothing else in the queue
+                        // we should bail entirely.  headBusy cannot have been set to true yet.
+                        runBackup = (mFullBackupQueue.size() > 1);
+                    } catch (RemoteException e) {
+                        // Cannot happen; the Activity Manager is in the same process
+                    }
+                }
+            } while (headBusy);
 
             if (!runBackup) {
                 if (DEBUG_SCHEDULING) {
@@ -4539,12 +4793,14 @@
                 return false;
             }
 
-            // Okay, the top thing is runnable now.  Pop it off and get going.
+            // Okay, the top thing is ready for backup now.  Do it.
             mFullBackupQueue.remove(0);
             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();
         }
 
@@ -8702,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 {
@@ -9727,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/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 37a6c02..df20704 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -753,6 +753,7 @@
         intentFilter.addAction(Intent.ACTION_USER_STOPPING);
         intentFilter.addAction(Intent.ACTION_USER_ADDED);
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
+        intentFilter.addAction(Intent.ACTION_USER_PRESENT);
         mContext.registerReceiverAsUser(
                 mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
 
@@ -1568,12 +1569,9 @@
         // load the global proxy at startup
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
 
-        // Try bringing up tracker, but if KeyStore isn't ready yet, wait
-        // for user to unlock device.
-        if (!updateLockdownVpn()) {
-            final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
-            mContext.registerReceiver(mUserPresentReceiver, filter);
-        }
+        // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait
+        // for user to unlock device too.
+        updateLockdownVpn();
 
         // Configure whether mobile data is always on.
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON));
@@ -1583,17 +1581,6 @@
         mPermissionMonitor.startMonitoring();
     }
 
-    private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            // Try creating lockdown tracker, since user present usually means
-            // unlocked keystore.
-            if (updateLockdownVpn()) {
-                mContext.unregisterReceiver(this);
-            }
-        }
-    };
-
     /**
      * Setup data activity tracking for the given network.
      *
@@ -3201,11 +3188,6 @@
         // Tear down existing lockdown if profile was removed
         mLockdownEnabled = LockdownVpnTracker.isEnabled();
         if (mLockdownEnabled) {
-            if (!mKeyStore.isUnlocked()) {
-                Slog.w(TAG, "KeyStore locked; unable to create LockdownTracker");
-                return false;
-            }
-
             final String profileName = new String(mKeyStore.get(Credentials.LOCKDOWN_VPN));
             final VpnProfile profile = VpnProfile.decode(
                     profileName, mKeyStore.get(Credentials.VPN + profileName));
@@ -3258,6 +3240,76 @@
         }
     }
 
+    /**
+     * Sets up or tears down the always-on VPN for user {@param user} as appropriate.
+     *
+     * @return {@code false} in case of errors; {@code true} otherwise.
+     */
+    private boolean updateAlwaysOnVpn(int user) {
+        final String lockdownPackage = getAlwaysOnVpnPackage(user);
+        if (lockdownPackage == null) {
+            return true;
+        }
+
+        // Create an intent to start the VPN service declared in the app's manifest.
+        Intent serviceIntent = new Intent(VpnConfig.SERVICE_INTERFACE);
+        serviceIntent.setPackage(lockdownPackage);
+
+        try {
+            return mContext.startServiceAsUser(serviceIntent, UserHandle.of(user)) != null;
+        } catch (RuntimeException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean setAlwaysOnVpnPackage(int userId, String packageName) {
+        enforceConnectivityInternalPermission();
+        enforceCrossUserPermission(userId);
+
+        // Can't set always-on VPN if legacy VPN is already in lockdown mode.
+        if (LockdownVpnTracker.isEnabled()) {
+            return false;
+        }
+
+        // If the current VPN package is the same as the new one, this is a no-op
+        final String oldPackage = getAlwaysOnVpnPackage(userId);
+        if (TextUtils.equals(oldPackage, packageName)) {
+            return true;
+        }
+
+        synchronized (mVpns) {
+            Vpn vpn = mVpns.get(userId);
+            if (vpn == null) {
+                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                return false;
+            }
+            if (!vpn.setAlwaysOnPackage(packageName)) {
+                return false;
+            }
+            if (!updateAlwaysOnVpn(userId)) {
+                vpn.setAlwaysOnPackage(null);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String getAlwaysOnVpnPackage(int userId) {
+        enforceConnectivityInternalPermission();
+        enforceCrossUserPermission(userId);
+
+        synchronized (mVpns) {
+            Vpn vpn = mVpns.get(userId);
+            if (vpn == null) {
+                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                return null;
+            }
+            return vpn.getAlwaysOnPackage();
+        }
+    }
+
     @Override
     public int checkMobileProvisioning(int suggestedTimeOutMs) {
         // TODO: Remove?  Any reason to trigger a provisioning check?
@@ -3514,6 +3566,11 @@
             userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId);
             mVpns.put(userId, userVpn);
         }
+        if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
+            updateLockdownVpn();
+        } else {
+            updateAlwaysOnVpn(userId);
+        }
     }
 
     private void onUserStop(int userId) {
@@ -3547,6 +3604,15 @@
         }
     }
 
+    private void onUserPresent(int userId) {
+        // User present may be sent because of an unlock, which might mean an unlocked keystore.
+        if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
+            updateLockdownVpn();
+        } else {
+            updateAlwaysOnVpn(userId);
+        }
+    }
+
     private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -3562,6 +3628,8 @@
                 onUserAdded(userId);
             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 onUserRemoved(userId);
+            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
+                onUserPresent(userId);
             }
         }
     };
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index bd95892..9bd79c9 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -50,11 +50,13 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IDeviceIdleController;
+import android.os.IMaintenanceActivityListener;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.Process;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
@@ -206,9 +208,13 @@
     private boolean mSyncActive;
     private boolean mJobsActive;
     private boolean mAlarmsActive;
+    private boolean mReportedMaintenanceActivity;
 
     public final AtomicFile mConfigFile;
 
+    private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
+            new RemoteCallbackList<IMaintenanceActivityListener>();
+
     /**
      * Package names the system has white-listed to opt out of power save restrictions,
      * except for device idle mode.
@@ -813,6 +819,7 @@
     static final int MSG_REPORT_IDLE_OFF = 4;
     static final int MSG_REPORT_ACTIVE = 5;
     static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
+    static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
 
     final class MyHandler extends Handler {
         MyHandler(Looper looper) {
@@ -902,6 +909,21 @@
                     int uid = msg.arg1;
                     checkTempAppWhitelistTimeout(uid);
                 } break;
+                case MSG_REPORT_MAINTENANCE_ACTIVITY: {
+                    boolean active = (msg.arg1 == 1);
+                    final int size = mMaintenanceActivityListeners.beginBroadcast();
+                    try {
+                        for (int i = 0; i < size; i++) {
+                            try {
+                                mMaintenanceActivityListeners.getBroadcastItem(i)
+                                        .onMaintenanceActivityChanged(active);
+                            } catch (RemoteException ignored) {
+                            }
+                        }
+                    } finally {
+                        mMaintenanceActivityListeners.finishBroadcast();
+                    }
+                } break;
             }
         }
     }
@@ -914,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() {
@@ -981,19 +1013,44 @@
         @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(
+                IMaintenanceActivityListener listener) {
+            return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
+        }
+
+        @Override public void unregisterMaintenanceActivityListener(
+                IMaintenanceActivityListener listener) {
+            DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
         }
 
         @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1704,6 +1761,7 @@
     void downloadServiceActive(IBinder token) {
         synchronized (this) {
             mDownloadServiceActive = token;
+            reportMaintenanceActivityIfNeededLocked();
             try {
                 token.linkToDeath(new IBinder.DeathRecipient() {
                     @Override public void binderDied() {
@@ -1719,6 +1777,7 @@
     void downloadServiceInactive() {
         synchronized (this) {
             mDownloadServiceActive = null;
+            reportMaintenanceActivityIfNeededLocked();
             exitMaintenanceEarlyIfNeededLocked();
         }
     }
@@ -1726,6 +1785,7 @@
     void setSyncActive(boolean active) {
         synchronized (this) {
             mSyncActive = active;
+            reportMaintenanceActivityIfNeededLocked();
             if (!active) {
                 exitMaintenanceEarlyIfNeededLocked();
             }
@@ -1735,6 +1795,7 @@
     void setJobsActive(boolean active) {
         synchronized (this) {
             mJobsActive = active;
+            reportMaintenanceActivityIfNeededLocked();
             if (!active) {
                 exitMaintenanceEarlyIfNeededLocked();
             }
@@ -1750,6 +1811,30 @@
         }
     }
 
+    boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
+        synchronized (this) {
+            mMaintenanceActivityListeners.register(listener);
+            return mReportedMaintenanceActivity;
+        }
+    }
+
+    void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
+        synchronized (this) {
+            mMaintenanceActivityListeners.unregister(listener);
+        }
+    }
+
+    void reportMaintenanceActivityIfNeededLocked() {
+        boolean active = mJobsActive | mSyncActive | (mDownloadServiceActive != null);
+        if (active == mReportedMaintenanceActivity) {
+            return;
+        }
+        mReportedMaintenanceActivity = active;
+        Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
+                mReportedMaintenanceActivity ? 1 : 0, 0);
+        mHandler.sendMessage(msg);
+    }
+
     void exitMaintenanceEarlyIfNeededLocked() {
         if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE) {
             if (mActiveIdleOpCount <= 0 && mDownloadServiceActive == null
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 15b5502..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);
                     }
                 }
             }
@@ -2537,7 +2539,7 @@
         }
         // By this IPC call, only a process which shares the same uid with the IME can add
         // additional input method subtypes to the IME.
-        if (TextUtils.isEmpty(imiId) || subtypes == null || subtypes.length == 0) return;
+        if (TextUtils.isEmpty(imiId) || subtypes == null) return;
         synchronized (mMethodMap) {
             final InputMethodInfo imi = mMethodMap.get(imiId);
             if (imi == null) return;
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 1a21f5c..377d52f 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -695,7 +695,7 @@
             unlockUser(userId, token);
 
             UserInfo info = UserManager.get(mContext).getUserInfo(userId);
-            if (LockPatternUtils.isSeparateWorkChallengeEnabled() && info.isManagedProfile()) {
+            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
                 TrustManager trustManager =
                         (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
                 trustManager.setDeviceLockedForUser(userId, false);
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
index 137fa27..816c791 100644
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -71,6 +71,7 @@
     private final Object mFileWriteLock = new Object();
 
     private int mStoredCredentialType;
+    private LockPatternUtils mLockPatternUtils;
 
     class CredentialHash {
         static final int TYPE_NONE = -1;
@@ -100,6 +101,7 @@
     public LockSettingsStorage(Context context, Callback callback) {
         mContext = context;
         mOpenHelper = new DatabaseHelper(context, callback);
+        mLockPatternUtils = new LockPatternUtils(context);
     }
 
     public void writeKeyValue(String key, String value, int userId) {
@@ -388,7 +390,7 @@
 
     private int getUserParentOrSelfId(int userId) {
         // Device supports per user encryption, so lock is applied to the given user.
-        if (LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
             return userId;
         }
         // Device uses Block Based Encryption, and the parent user's lock is used for the whole
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 11f9e2d..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);
@@ -2312,6 +2313,14 @@
         }
 
         final 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);
+        }
+
         final int userId = UserHandle.getUserId(uid);
         if (!canUserModifyAccounts(userId, uid)) {
             try {
@@ -2483,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());
@@ -2499,6 +2508,14 @@
         }
 
         final int uid = Binder.getCallingUid();
+        // Only allow system to finish session
+        if (!isSystemUid(uid)) {
+            String msg = String.format(
+                    "uid %s cannot finish session.",
+                    uid);
+            throw new SecurityException(msg);
+        }
+
         final int userId = UserHandle.getUserId(uid);
         if (!canUserModifyAccounts(userId, uid)) {
             sendErrorResponse(response,
@@ -2717,6 +2734,16 @@
         if (account == null) {
             throw new IllegalArgumentException("account is null");
         }
+
+        final int uid = Binder.getCallingUid();
+        // Only allow system to start session
+        if (!isSystemUid(uid)) {
+            String msg = String.format(
+                    "uid %s cannot start update credentials session.",
+                    uid);
+            throw new SecurityException(msg);
+        }
+
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
@@ -2752,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();
@@ -2793,6 +2913,25 @@
         }
     }
 
+    @Override
+    public boolean someUserHasAccount(@NonNull final Account account) {
+        if (!UserHandle.isSameApp(Process.SYSTEM_UID, Binder.getCallingUid())) {
+            throw new SecurityException("Only system can check for accounts across users");
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            AccountAndUser[] allAccounts = getAllAccounts();
+            for (int i = allAccounts.length - 1; i >= 0; i--) {
+                if (allAccounts[i].account.equals(account)) {
+                    return true;
+                }
+            }
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     private class GetAccountsByTypeAndFeatureSession extends Session {
         private final String[] mFeatures;
         private volatile Account[] mAccountsOfType = null;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index d12eadb..7ba6338 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -61,6 +61,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -326,7 +327,7 @@
 
         ServiceLookupResult res =
             retrieveServiceLocked(service, resolvedType, callingPackage,
-                    callingPid, callingUid, userId, true, callerFg);
+                    callingPid, callingUid, userId, true, callerFg, false);
         if (res == null) {
             return null;
         }
@@ -549,7 +550,7 @@
 
         // If this service is active, make sure it is stopped.
         ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null,
-                Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
+                Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false);
         if (r != null) {
             if (r.record != null) {
                 final long origId = Binder.clearCallingIdentity();
@@ -598,7 +599,7 @@
     IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
         ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage,
                 Binder.getCallingPid(), Binder.getCallingUid(),
-                UserHandle.getCallingUserId(), false, false);
+                UserHandle.getCallingUserId(), false, false, false);
 
         IBinder ret = null;
         if (r != null) {
@@ -831,10 +832,11 @@
         }
 
         final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
+        final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
 
         ServiceLookupResult res =
-            retrieveServiceLocked(service, resolvedType, callingPackage,
-                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
+            retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
+                    Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
         if (res == null) {
             return 0;
         }
@@ -1192,7 +1194,7 @@
 
     private ServiceLookupResult retrieveServiceLocked(Intent service,
             String resolvedType, String callingPackage, int callingPid, int callingUid, int userId,
-            boolean createIfNeeded, boolean callingFromFg) {
+            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal) {
         ServiceRecord r = null;
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
                 + " type=" + resolvedType + " callingUid=" + callingUid);
@@ -1205,10 +1207,16 @@
         if (comp != null) {
             r = smap.mServicesByName.get(comp);
         }
-        if (r == null) {
+        if (r == null && !isBindExternal) {
             Intent.FilterComparison filter = new Intent.FilterComparison(service);
             r = smap.mServicesByIntent.get(filter);
         }
+        if (r != null && (r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
+                && !callingPackage.equals(r.packageName)) {
+            // If an external service is running within its own package, other packages
+            // should not bind to that instance.
+            r = null;
+        }
         if (r == null) {
             try {
                 // TODO: come back and remove this assumption to triage all services
@@ -1225,6 +1233,37 @@
                 }
                 ComponentName name = new ComponentName(
                         sInfo.applicationInfo.packageName, sInfo.name);
+                if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
+                    if (isBindExternal) {
+                        if (!sInfo.exported) {
+                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
+                                    " is not exported");
+                        }
+                        if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
+                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
+                                    " is not an isolatedProcess");
+                        }
+                        // Run the service under the calling package's application.
+                        ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
+                                callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);
+                        if (aInfo == null) {
+                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " +
+                                    "could not resolve client package " + callingPackage);
+                        }
+                        sInfo = new ServiceInfo(sInfo);
+                        sInfo.applicationInfo = new ApplicationInfo(sInfo.applicationInfo);
+                        sInfo.applicationInfo.packageName = aInfo.packageName;
+                        sInfo.applicationInfo.uid = aInfo.uid;
+                        name = new ComponentName(aInfo.packageName, name.getClassName());
+                        service.setComponent(name);
+                    } else {
+                        throw new SecurityException("BIND_EXTERNAL_SERVICE required for " +
+                                name);
+                    }
+                } else if (isBindExternal) {
+                    throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
+                            " is not an externalService");
+                }
                 if (userId > 0) {
                     if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                             sInfo.name, sInfo.flags)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 093a33d..adb11a4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,7 +18,6 @@
 
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
-
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.AssistUtils;
@@ -202,6 +201,7 @@
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.util.TimeUtils;
 import android.util.Xml;
 import android.view.Display;
@@ -240,6 +240,7 @@
 import java.util.concurrent.atomic.AtomicLong;
 
 import dalvik.system.VMRuntime;
+
 import libcore.io.IoUtils;
 import libcore.util.EmptyArray;
 
@@ -565,7 +566,7 @@
     /**
      * List of intents that were used to start the most recent tasks.
      */
-    private final RecentTasks mRecentTasks;
+    final RecentTasks mRecentTasks;
 
     /**
      * For addAppTask: cached of the last activity component that was added.
@@ -1053,11 +1054,6 @@
     final AppOpsService mAppOpsService;
 
     /**
-     * Save recent tasks information across reboots.
-     */
-    final TaskPersister mTaskPersister;
-
-    /**
      * Current configuration information.  HistoryRecord objects are given
      * a reference to this object to indicate which configuration they are
      * currently running in, so this object must be kept immutable.
@@ -1479,6 +1475,7 @@
     final ServiceThread mHandlerThread;
     final MainHandler mHandler;
     final UiHandler mUiHandler;
+    final ProcessStartLogger mProcessStartLogger;
 
     PackageManagerInternal mPackageManagerInt;
 
@@ -2456,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,
@@ -2509,10 +2508,10 @@
 
         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
-        mRecentTasks = new RecentTasks(this);
-        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
+        mStackSupervisor = new ActivityStackSupervisor(this);
         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
-        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
+        mRecentTasks = new RecentTasks(this, mStackSupervisor);
+
 
         mProcessCpuThread = new Thread("CpuTracker") {
             @Override
@@ -2566,6 +2565,10 @@
         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
     }
 
+    void onUserStoppedLocked(int userId) {
+        mRecentTasks.unloadUserRecentsLocked(userId);
+    }
+
     public void initPowerManagement() {
         mStackSupervisor.initPowerManagement();
         mBatteryStatsService.initPowerManagement();
@@ -3552,6 +3555,8 @@
                     app.processName, hostingType,
                     hostingNameStr != null ? hostingNameStr : "");
 
+            mProcessStartLogger.logIfNeededLocked(app, startResult);
+
             if (app.persistent) {
                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
             }
@@ -5475,7 +5480,7 @@
                     return;
                 }
                 killPackageProcessesLocked(packageName, appId, userId,
-                        ProcessList.SERVICE_ADJ, false, true, true, false, true, "kill background");
+                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -5777,7 +5782,7 @@
 
     private final boolean killPackageProcessesLocked(String packageName, int appId,
             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
-            boolean doit, boolean evenPersistent, boolean killPackageApp, String reason) {
+            boolean doit, boolean evenPersistent, String reason) {
         ArrayList<ProcessRecord> procs = new ArrayList<>();
 
         // Remove all processes this package may have touched: all with the
@@ -5826,7 +5831,7 @@
                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
                         continue;
                     }
-                    if ((!killPackageApp || !app.pkgList.containsKey(packageName)) && !isDep) {
+                    if (!app.pkgList.containsKey(packageName) && !isDep) {
                         continue;
                     }
                 }
@@ -5992,7 +5997,7 @@
         }
 
         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
-                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent, true,
+                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
 
         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
@@ -6634,6 +6639,8 @@
             }
         }, dumpheapFilter);
 
+        mProcessStartLogger.registerListener(mContext);
+
         // Let system services know.
         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
 
@@ -7256,6 +7263,17 @@
     }
 
     @Override
+    public boolean isAppForeground(int uid) throws RemoteException {
+        synchronized (this) {
+            UidRecord uidRec = mActiveUids.get(uid);
+            if (uidRec == null || uidRec.idle) {
+                return false;
+            }
+            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+        }
+    }
+
+    @Override
     public boolean inMultiWindowMode(IBinder token) {
         final long origId = Binder.clearCallingIdentity();
         try {
@@ -8851,6 +8869,8 @@
                     android.Manifest.permission.GET_DETAILED_TASKS)
                     == PackageManager.PERMISSION_GRANTED;
 
+            mRecentTasks.loadUserRecentsLocked(userId);
+
             final int recentsCount = mRecentTasks.size();
             ArrayList<ActivityManager.RecentTaskInfo> res =
                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
@@ -9013,8 +9033,9 @@
                 thumbnailInfo.taskHeight = displaySize.y;
                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
 
-                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
-                        intent, description, thumbnailInfo);
+                TaskRecord task = new TaskRecord(this,
+                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
+                        ainfo, intent, description, thumbnailInfo);
 
                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
                 if (trimIdx >= 0) {
@@ -9173,9 +9194,10 @@
                 passedIconFile.getName());
         if (!legitIconFile.getPath().equals(filePath)
                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
-            throw new IllegalArgumentException("Bad file path: " + filePath);
+            throw new IllegalArgumentException("Bad file path: " + filePath
+                    + " passed for userId " + userId);
         }
-        return mTaskPersister.getTaskDescriptionIcon(filePath);
+        return mRecentTasks.getTaskDescriptionIcon(filePath);
     }
 
     @Override
@@ -11145,11 +11167,7 @@
 
     /** Pokes the task persister. */
     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
-        if (task != null && task.stack != null && task.stack.isHomeStack()) {
-            // Never persist the home stack.
-            return;
-        }
-        mTaskPersister.wakeup(task, flush);
+        mRecentTasks.notifyTaskPersisterLocked(task, flush);
     }
 
     /** Notifies all listeners when the task stack has changed. */
@@ -11254,9 +11272,13 @@
                     + android.Manifest.permission.DEVICE_POWER);
         }
 
+        final int user = UserHandle.myUserId();
         synchronized(this) {
             long ident = Binder.clearCallingIdentity();
             try {
+                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
+                    startHomeActivityLocked(user, "setLockScreenShown");
+                }
                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
                 updateSleepIfNeededLocked();
@@ -12113,7 +12135,7 @@
             final long identity = Binder.clearCallingIdentity();
             try {
                 killPackageProcessesLocked(null, appId, userId,
-                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true, true,
+                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
                         reason != null ? reason : "kill uid");
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -12562,11 +12584,7 @@
             // security checks.
             mUserController.updateCurrentProfileIdsLocked();
 
-            mRecentTasks.clear();
-            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
-            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
-            mTaskPersister.startPersisting();
-
+            mRecentTasks.onSystemReady();
             // Check to see if there are any update receivers to run.
             if (!mDidUpdate) {
                 if (mWaitingUpdate) {
@@ -12673,7 +12691,6 @@
 
         if (goingCallback != null) goingCallback.run();
 
-
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
                 Integer.toString(currentUserId), currentUserId);
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
@@ -18155,7 +18172,7 @@
     }
 
     @Override
-    public void moveTasksToFullscreenStack(int fromStackId) {
+    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
         if (fromStackId == HOME_STACK_ID) {
             throw new IllegalArgumentException("You can't move tasks from the home stack.");
@@ -18165,9 +18182,18 @@
             final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
             if (stack != null) {
                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
-                for (int i = tasks.size() - 1; i >= 0; i--) {
-                    mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
-                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
+                final int size = tasks.size();
+                if (onTop) {
+                    for (int i = 0; i < size; i++) {
+                        mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
+                                FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, !FORCE_FOCUS,
+                                "moveTasksToFullscreenStack", ANIMATE);
+                    }
+                } else {
+                    for (int i = size - 1; i >= 0; i--) {
+                        mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
+                                FULLSCREEN_WORKSPACE_STACK_ID, 0);
+                    }
                 }
             }
             Binder.restoreCallingIdentity(origId);
@@ -20818,10 +20844,6 @@
         return mUserController.stopUser(userId, force, callback);
     }
 
-    void onUserRemovedLocked(int userId) {
-        mRecentTasks.removeTasksForUserLocked(userId);
-    }
-
     @Override
     public UserInfo getCurrentUser() {
         return mUserController.getCurrentUser();
@@ -20876,6 +20898,10 @@
         return newInfo;
     }
 
+    public boolean isUserStopped(int userId) {
+        return mUserController.getStartedUserStateLocked(userId) == null;
+    }
+
     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
         if (aInfo == null
                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
@@ -21028,7 +21054,7 @@
         @Override
         public void onUserRemoved(int userId) {
             synchronized (ActivityManagerService.this) {
-                ActivityManagerService.this.onUserRemovedLocked(userId);
+                ActivityManagerService.this.onUserStoppedLocked(userId);
             }
         }
     }
@@ -21117,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
@@ -21175,7 +21206,8 @@
     public void killPackageDependents(String packageName, int userId) {
         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
         if (packageName == null) {
-            throw new NullPointerException("Cannot kill the dependents of a package without its name.");
+            throw new NullPointerException(
+                    "Cannot kill the dependents of a package without its name.");
         }
 
         long callingId = Binder.clearCallingIdentity();
@@ -21186,12 +21218,13 @@
         } catch (RemoteException e) {
         }
         if (pkgUid == -1) {
-            throw new IllegalArgumentException("Cannot kill dependents of non-existing package " + packageName);
+            throw new IllegalArgumentException(
+                    "Cannot kill dependents of non-existing package " + packageName);
         }
         try {
             synchronized(this) {
                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
-                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, false,
+                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
                         "dep: " + packageName);
             }
         } finally {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 13c1417..8c99739 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -21,6 +21,8 @@
 import android.os.ShellCommand;
 import android.os.UserHandle;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.io.PrintWriter;
 
 class ActivityManagerShellCommand extends ShellCommand {
@@ -58,6 +60,8 @@
                     return runTrackAssociations(pw);
                 case "untrack-associations":
                     return runUntrackAssociations(pw);
+                case "is-user-stopped":
+                    return runIsUserStopped(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -67,6 +71,13 @@
         return -1;
     }
 
+    int runIsUserStopped(PrintWriter pw) {
+        int userId = UserHandle.parseUserArg(getNextArgRequired());
+        boolean stopped = mInternal.isUserStopped(userId);
+        pw.println(stopped);
+        return 0;
+    }
+
     int runForceStop(PrintWriter pw) throws RemoteException {
         int userId = UserHandle.USER_ALL;
 
@@ -107,7 +118,7 @@
     int runWrite(PrintWriter pw) {
         mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
                 "registerUidObserver()");
-        mInternal.mTaskPersister.flush();
+        mInternal.mRecentTasks.flush();
         pw.println("All tasks persisted.");
         return 0;
     }
@@ -190,6 +201,8 @@
             pw.println("    Enable association tracking.");
             pw.println("  untrack-associations");
             pw.println("    Disable and clear association tracking.");
+            pw.println("  is-user-stopped <USER_ID>");
+            pw.println("    returns whether <USER_ID> has been stopped or not");
         }
     }
 }
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 4101dde..ffb2fc4 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -5,6 +5,7 @@
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
 
 import android.app.ActivityManager.StackId;
 import android.content.Context;
@@ -51,7 +52,7 @@
         mLastLogTimeSecs = now;
 
         ActivityStack stack = mSupervisor.getStack(DOCKED_STACK_ID);
-        if (stack != null && stack.isStackVisibleLocked()) {
+        if (stack != null && stack.getStackVisibilityLocked() != STACK_INVISIBLE) {
             mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
             return;
         }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index eb0945bf..b16bd2b 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1268,7 +1268,7 @@
             final String iconFilename = createImageFilename(createTime, task.taskId);
             final File iconFile = new File(TaskPersister.getUserImagesDir(userId), iconFilename);
             final String iconFilePath = iconFile.getAbsolutePath();
-            mStackSupervisor.mService.mTaskPersister.saveImage(icon, iconFilePath);
+            service.mRecentTasks.saveImage(icon, iconFilePath);
             _taskDescription.setIconFilename(iconFilePath);
         }
         taskDescription = _taskDescription;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 312e309..e3f4999 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -166,6 +166,14 @@
         DESTROYED
     }
 
+    // Stack is not considered visible.
+    static final int STACK_INVISIBLE = 0;
+    // Stack is considered visible
+    static final int STACK_VISIBLE = 1;
+    // Stack is considered visible, but only becuase it has activity that is visible behind other
+    // activities and there is a specific combination of stacks.
+    static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2;
+
     final ActivityManagerService mService;
     final WindowManagerService mWindowManager;
     private final RecentTasks mRecentTasks;
@@ -1179,8 +1187,12 @@
             prev.cpuTimeAtResume = 0; // reset it
         }
 
-        // Notfiy when the task stack has changed
-        mService.notifyTaskStackChangedLocked();
+        // Notify when the task stack has changed, but only if visibilities changed (not just
+        // focus).
+        if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause) {
+            mService.notifyTaskStackChangedLocked();
+            mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
+        }
     }
 
     private void addToStopping(ActivityRecord r) {
@@ -1257,6 +1269,7 @@
             ActivityContainer container = containers.get(containerNdx);
             container.setVisible(visible);
         }
+        mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
     }
 
     // Find the first visible activity above the passed activity and if it is translucent return it
@@ -1316,7 +1329,8 @@
         if (stacks != null) {
             for (int i = stacks.size() - 1; i >= 0; --i) {
                 ActivityStack stack = stacks.get(i);
-                if (stack != this && stack.isFocusable() && stack.isStackVisibleLocked()) {
+                if (stack != this && stack.isFocusable()
+                        && stack.getStackVisibilityLocked() != STACK_INVISIBLE) {
                     return stack;
                 }
             }
@@ -1358,14 +1372,17 @@
         return true;
     }
 
-    /** Returns true if the stack is considered visible. */
-    boolean isStackVisibleLocked() {
+    /**
+     * Returns stack's visibility: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE} or
+     * {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
+     */
+    int getStackVisibilityLocked() {
         if (!isAttached()) {
-            return false;
+            return STACK_INVISIBLE;
         }
 
         if (mStackSupervisor.isFrontStack(this) || mStackSupervisor.isFocusedStack(this)) {
-            return true;
+            return STACK_VISIBLE;
         }
 
         final int stackIndex = mStacks.indexOf(this);
@@ -1373,32 +1390,34 @@
         if (stackIndex == mStacks.size() - 1) {
             Slog.wtf(TAG,
                     "Stack=" + this + " isn't front stack but is at the top of the stack list");
-            return false;
+            return STACK_INVISIBLE;
         }
 
         final boolean isLockscreenShown = mService.mLockScreenShown == LOCK_SCREEN_SHOWN;
         if (isLockscreenShown && !StackId.isAllowedOverLockscreen(mStackId)) {
-            return false;
+            return STACK_INVISIBLE;
         }
 
         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
         final int focusedStackId = focusedStack.mStackId;
 
         if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID
-                && hasVisibleBehindActivity() && focusedStackId == HOME_STACK_ID) {
+                && hasVisibleBehindActivity() && focusedStackId == HOME_STACK_ID
+                && !focusedStack.topActivity().fullscreen) {
             // The fullscreen stack should be visible if it has a visible behind activity behind
-            // the home stack that will be translucent.
-            return true;
+            // the home stack that is translucent.
+            return STACK_VISIBLE_ACTIVITY_BEHIND;
         }
 
         if (mStackId == DOCKED_STACK_ID) {
             // Docked stack is always visible, except in the case where the home activity
             // is the top running activity in the focused home stack.
             if (focusedStackId != HOME_STACK_ID) {
-                return true;
+                return STACK_VISIBLE;
             }
             ActivityRecord topHomeActivity = focusedStack.topRunningActivityLocked();
-            return topHomeActivity == null || !topHomeActivity.isHomeActivity();
+            return topHomeActivity == null || !topHomeActivity.isHomeActivity() ?
+                    STACK_VISIBLE : STACK_INVISIBLE;
         }
 
         // Find the first stack below focused stack that actually got something visible.
@@ -1410,7 +1429,7 @@
         if ((focusedStackId == DOCKED_STACK_ID || focusedStackId == PINNED_STACK_ID)
                 && stackIndex == belowFocusedIndex) {
             // Stacks directly behind the docked or pinned stack are always visible.
-            return true;
+            return STACK_VISIBLE;
         }
 
         if (focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
@@ -1419,7 +1438,7 @@
             // visible so they can act as a backdrop to the translucent activity.
             // For example, dialog activities
             if (stackIndex == belowFocusedIndex) {
-                return true;
+                return STACK_VISIBLE;
             }
             if (belowFocusedIndex >= 0) {
                 final ActivityStack stack = mStacks.get(belowFocusedIndex);
@@ -1427,14 +1446,14 @@
                         && stackIndex == (belowFocusedIndex - 1)) {
                     // The stack behind the docked or pinned stack is also visible so we can have a
                     // complete backdrop to the translucent activity when the docked stack is up.
-                    return true;
+                    return STACK_VISIBLE;
                 }
             }
         }
 
         if (StackId.isStaticStack(mStackId)) {
             // Visibility of any static stack should have been determined by the conditions above.
-            return false;
+            return STACK_INVISIBLE;
         }
 
         for (int i = stackIndex + 1; i < mStacks.size(); i++) {
@@ -1446,15 +1465,15 @@
 
             if (!StackId.isDynamicStacksVisibleBehindAllowed(stack.mStackId)) {
                 // These stacks can't have any dynamic stacks visible behind them.
-                return false;
+                return STACK_INVISIBLE;
             }
 
             if (!hasTranslucentActivity(stack)) {
-                return false;
+                return STACK_INVISIBLE;
             }
         }
 
-        return true;
+        return STACK_VISIBLE;
     }
 
     final int rankTaskLayers(int baseLayer) {
@@ -1487,14 +1506,16 @@
         // If the top activity is not fullscreen, then we need to
         // make sure any activities under it are now visible.
         boolean aboveTop = top != null;
-        final boolean stackInvisible = !isStackVisibleLocked();
+        final int stackVisibility = getStackVisibilityLocked();
+        final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
+        final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
         boolean behindFullscreenActivity = stackInvisible;
         boolean resumeNextActivity = isFocusable() && (isInStackLocked(starting) == null);
-
+        boolean behindTranslucentActivity = false;
+        final ActivityRecord visibleBehind = getVisibleBehindActivity();
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             final TaskRecord task = mTaskHistory.get(taskNdx);
             final ArrayList<ActivityRecord> activities = task.mActivities;
-
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = activities.get(activityNdx);
                 if (r.finishing) {
@@ -1507,11 +1528,13 @@
                 aboveTop = false;
                 // mLaunchingBehind: Activities launching behind are at the back of the task stack
                 // but must be drawn initially for the animation as though they were visible.
-                if ((!behindFullscreenActivity || r.mLaunchTaskBehind)
-                        && okToShowLocked(r)) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                            "Make visible? " + r + " finishing=" + r.finishing
-                            + " state=" + r.state);
+                final boolean activityVisibleBehind =
+                        (behindTranslucentActivity || stackVisibleBehind) && visibleBehind == r;
+                final boolean isVisible = (!behindFullscreenActivity || r.mLaunchTaskBehind
+                        || activityVisibleBehind) && okToShowLocked(r);
+                if (isVisible) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
+                            + " finishing=" + r.finishing + " state=" + r.state);
                     // First: if this is not the current activity being started, make
                     // sure it matches the current configuration.
                     if (r != starting) {
@@ -1540,15 +1563,23 @@
                     configChanges |= r.configChangeFlags;
                     behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
                             behindFullscreenActivity, task, r);
+                    if (behindFullscreenActivity && !r.fullscreen) {
+                        behindTranslucentActivity = true;
+                    }
                 } else {
-                    makeInvisible(stackInvisible, behindFullscreenActivity, r);
+                    if (DEBUG_VISIBILITY || true) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+                            + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
+                            + stackInvisible + " behindFullscreenActivity="
+                            + behindFullscreenActivity + " mLaunchTaskBehind="
+                            + r.mLaunchTaskBehind);
+                    makeInvisible(r, visibleBehind);
                 }
             }
             if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
                 // The visibility of tasks and the activities they contain in freeform stack are
                 // determined individually unlike other stacks where the visibility or fullscreen
                 // status of an activity in a previous task affects other.
-                behindFullscreenActivity = stackInvisible;
+                behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
             }
         }
 
@@ -1596,18 +1627,14 @@
         return false;
     }
 
-    private void makeInvisible(boolean stackInvisible, boolean behindFullscreenActivity,
-            ActivityRecord r) {
-        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r + " finishing="
-                + r.finishing + " state=" + r.state + " stackInvisible=" + stackInvisible
-                + " behindFullscreenActivity=" + behindFullscreenActivity);
+    private void makeInvisible(ActivityRecord r, ActivityRecord visibleBehind) {
         if (!r.visible) {
             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
             return;
         }
         // Now for any activities that aren't visible to the user, make sure they no longer are
         // keeping the screen frozen.
-        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r);
+        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.state);
         try {
             setVisible(r, false);
             switch (r.state) {
@@ -1626,7 +1653,7 @@
                 case PAUSED:
                     // This case created for transitioning activities from
                     // translucent to opaque {@link Activity#convertToOpaque}.
-                    if (getVisibleBehindActivity() == r) {
+                    if (visibleBehind == r) {
                         releaseBackgroundResources(r);
                     } else {
                         if (!mStackSupervisor.mStoppingActivities.contains(r)) {
@@ -1648,16 +1675,16 @@
     private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity,
             TaskRecord task, ActivityRecord r) {
         if (r.fullscreen) {
-            // At this point, nothing else needs to be shown in this task.
-            behindFullscreenActivity = true;
             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
                     + " stackInvisible=" + stackInvisible
                     + " behindFullscreenActivity=" + behindFullscreenActivity);
-        } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
+            // At this point, nothing else needs to be shown in this task.
             behindFullscreenActivity = true;
+        } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
                     + " stackInvisible=" + stackInvisible
                     + " behindFullscreenActivity=" + behindFullscreenActivity);
+            behindFullscreenActivity = true;
         }
         return behindFullscreenActivity;
     }
@@ -2590,8 +2617,9 @@
                     if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
                             + " out to bottom task " + bottom.task);
                 } else {
-                    targetTask = createTaskRecord(mStackSupervisor.getNextTaskId(), target.info,
-                            null, null, null, false);
+                    targetTask = createTaskRecord(
+                            mStackSupervisor.getNextTaskIdForUserLocked(target.userId),
+                            target.info, null, null, null, false);
                     targetTask.affinityIntent = target.intent;
                     if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
                             + " out to new task " + target.task);
@@ -3713,9 +3741,9 @@
     void releaseBackgroundResources(ActivityRecord r) {
         if (hasVisibleBehindActivity() &&
                 !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
-            if (r == topRunningActivityLocked()) {
+            if (r == topRunningActivityLocked() && getStackVisibilityLocked() == STACK_VISIBLE) {
                 // Don't release the top activity if it has requested to run behind the next
-                // activity.
+                // activity and the stack is currently visible.
                 return;
             }
             if (DEBUG_STATES) Slog.d(TAG_STATES, "releaseBackgroundResources activtyDisplay=" +
@@ -4753,8 +4781,7 @@
     }
 
     void addConfigOverride(ActivityRecord r, TaskRecord task) {
-        final Rect bounds = task.getLaunchBounds();
-        task.updateOverrideConfiguration(bounds);
+        final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds();
         mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                 (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges,
@@ -4798,7 +4825,8 @@
         final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r);
 
         final TaskRecord task = createTaskRecord(
-                mStackSupervisor.getNextTaskId(), r.info, r.intent, null, null, true);
+                mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
+                r.info, r.intent, null, null, true);
         r.setTask(task, null);
         task.addActivityToTop(r);
         setAppTask(r, task);
@@ -4810,10 +4838,9 @@
     }
 
     private void setAppTask(ActivityRecord r, TaskRecord task) {
-        final Rect bounds = task.getLaunchBounds();
-        task.updateOverrideConfiguration(bounds);
+        final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds();
         mWindowManager.setAppTask(
-                r.appToken, task.taskId, mStackId, task.getLaunchBounds(), task.mOverrideConfig);
+                r.appToken, task.taskId, mStackId, bounds, task.mOverrideConfig);
         mWindowManager.setTaskResizeable(task.taskId, task.mResizeable);
         r.taskConfigOverride = task.mOverrideConfig;
     }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c634e0e..d9dd77d 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -262,10 +262,12 @@
     // For debugging to make sure the caller when acquiring/releasing our
     // wake lock is the system process.
     static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
+    /** The number of distinct task ids that can be assigned to the tasks of a single user */
+    private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;
 
     final ActivityManagerService mService;
 
-    private final RecentTasks mRecentTasks;
+    private RecentTasks mRecentTasks;
 
     final ActivityStackSupervisorHandler mHandler;
 
@@ -276,9 +278,11 @@
     /** Counter for next free stack ID to use for dynamic activity stacks. */
     private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID;
 
-    /** Task identifier that activities are currently being started in.  Incremented each time a
-     * new task is created. */
-    private int mCurTaskId = 0;
+    /**
+     * Maps the task identifier that activities are currently being started in to the userId of the
+     * task. Each time a new task is created, the entry for the userId of the task is incremented
+     */
+    private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20);
 
     /** The current user */
     int mCurrentUser;
@@ -399,6 +403,12 @@
     private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
 
     /**
+     * Used to keep track whether app visibilities got changed since the last pause. Useful to
+     * determine whether to invoke the task stack change listener after pausing.
+     */
+    boolean mAppVisibilitiesChangedSinceLastPause;
+
+    /**
      * Description of a request to start a new activity, which has been held
      * due to app switches being disabled.
      */
@@ -430,14 +440,17 @@
         }
     }
 
-    public ActivityStackSupervisor(ActivityManagerService service, RecentTasks recentTasks) {
+    public ActivityStackSupervisor(ActivityManagerService service) {
         mService = service;
-        mRecentTasks = recentTasks;
         mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
         mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
         mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
     }
 
+    void setRecentTasks(RecentTasks recentTasks) {
+        mRecentTasks = recentTasks;
+    }
+
     /**
      * At the time when the constructor runs, the power manager has not yet been
      * initialized.  So we initialize our wakelocks afterwards.
@@ -679,20 +692,43 @@
         return null;
     }
 
-    void setNextTaskId(int taskId) {
-        if (taskId > mCurTaskId) {
-            mCurTaskId = taskId;
+    boolean isFocusedUserLockedProfile() {
+        final int userId = mFocusedStack.topRunningActivityLocked().userId;
+        return userId != UserHandle.myUserId()
+                && mService.mUserController.shouldConfirmCredentials(userId);
+    }
+
+    void setNextTaskIdForUserLocked(int taskId, int userId) {
+        final int currentTaskId = mCurTaskIdForUser.get(userId, -1);
+        if (taskId > currentTaskId) {
+            mCurTaskIdForUser.put(userId, taskId);
         }
     }
 
-    int getNextTaskId() {
-        do {
-            mCurTaskId++;
-            if (mCurTaskId <= 0) {
-                mCurTaskId = 1;
+    int getNextTaskIdForUserLocked(int userId) {
+        mRecentTasks.loadUserRecentsLocked(userId);
+        final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER);
+        // for a userId u, a taskId can only be in the range
+        // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER
+        // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
+        int candidateTaskId = currentTaskId;
+        while (anyTaskForIdLocked(candidateTaskId, !RESTORE_FROM_RECENTS,
+                INVALID_STACK_ID) != null) {
+            candidateTaskId++;
+            if (candidateTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) {
+                // Wrap around as there will be smaller task ids that are available now.
+                candidateTaskId -= MAX_TASK_IDS_PER_USER;
             }
-        } while (anyTaskForIdLocked(mCurTaskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID) != null);
-        return mCurTaskId;
+            if (candidateTaskId == currentTaskId) {
+                // Something wrong!
+                // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user
+                throw new IllegalStateException("Cannot get an available task id."
+                        + " Reached limit of " + MAX_TASK_IDS_PER_USER
+                        + " running tasks per user.");
+            }
+        }
+        mCurTaskIdForUser.put(userId, candidateTaskId);
+        return candidateTaskId;
     }
 
     ActivityRecord resumedAppLocked() {
@@ -1673,7 +1709,7 @@
         if (task.mResizeable && options != null) {
             int stackId = options.getLaunchStackId();
             if (canUseActivityOptionsLaunchBounds(options, stackId)) {
-                Rect bounds = options.getLaunchBounds();
+                final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds());
                 task.updateOverrideConfiguration(bounds);
                 if (stackId == INVALID_STACK_ID) {
                     stackId = task.getLaunchStackId();
@@ -1683,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 */);
+                }
             }
         }
 
@@ -1841,6 +1883,7 @@
             // can have the right fullscreen state.
             bounds = null;
         }
+        bounds = TaskRecord.validateBounds(bounds);
 
         mTmpBounds.clear();
         mTmpConfigs.clear();
@@ -1857,8 +1900,8 @@
                     fitWithinBounds(tempRect2, bounds);
                     task.updateOverrideConfiguration(tempRect2);
                 } else {
-                    task.updateOverrideConfiguration(tempTaskBounds != null
-                            ? tempTaskBounds : bounds);
+                    task.updateOverrideConfiguration(
+                            tempTaskBounds != null ? tempTaskBounds : bounds);
                 }
             }
 
@@ -1933,7 +1976,8 @@
                 // static stacks need to be adjusted so they don't overlap with the docked stack.
                 // We get the bounds to use from window manager which has been adjusted for any
                 // screen controls and is also the same for all stacks.
-                mWindowManager.getStackDockedModeBounds(HOME_STACK_ID, tempRect);
+                mWindowManager.getStackDockedModeBounds(
+                        HOME_STACK_ID, tempRect, true /* ignoreVisibilityOnKeyguardShowing */);
                 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
                     if (StackId.isResizeableByDockedStack(i)) {
                         ActivityStack otherStack = getStack(i);
@@ -1973,6 +2017,7 @@
             // Nothing to do here...
             return true;
         }
+        bounds = TaskRecord.validateBounds(bounds);
 
         if (!mWindowManager.isValidTaskId(task.taskId)) {
             // Task doesn't exist in window manager yet (e.g. was restored from recents).
@@ -2796,7 +2841,8 @@
         pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
                 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
         pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
-        pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
+        pw.print(prefix);
+        pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
         pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
         pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index cfa4433..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;
@@ -60,9 +62,11 @@
 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
 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;
 
@@ -226,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) {
@@ -875,7 +890,7 @@
                 // In this situation we want to remove all activities from the task up to the one
                 // being started. In most cases this means we are resetting the task to its initial
                 // state.
-                final ActivityRecord top = intentActivity.task.performClearTaskLocked(
+                final ActivityRecord top = intentActivity.task.performClearTaskForReuseLocked(
                         mStartActivity, mLaunchFlags);
                 if (top != null) {
                     if (top.frontOfTask) {
@@ -1033,7 +1048,8 @@
     }
 
     private void launchRecentsAppIfNeeded(ActivityStack topStack) {
-        if (topStack.mStackId == HOME_STACK_ID && mTargetStack.mStackId == DOCKED_STACK_ID) {
+        if (topStack.mStackId == HOME_STACK_ID && mTargetStack != null
+                && mTargetStack.mStackId == DOCKED_STACK_ID) {
             // We launch an activity while being in home stack, which means either launcher or
             // recents into docked stack. We don't want the launched activity to be alone in a
             // docked stack, so we want to immediately launch recents too.
@@ -1420,13 +1436,21 @@
         }
 
         if (mReuseTask == null) {
-            final TaskRecord task = mTargetStack.createTaskRecord(mSupervisor.getNextTaskId(),
+            final TaskRecord task = mTargetStack.createTaskRecord(
+                    mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                     mNewTaskIntent != null ? mNewTaskIntent : mIntent,
                     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 " +
@@ -1509,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(
@@ -1552,9 +1581,9 @@
             mTargetStack.moveToFront("addingToTopTask");
         }
         final ActivityRecord prev = mTargetStack.topActivity();
-        final TaskRecord task = prev != null ? prev.task
-                : mTargetStack.createTaskRecord(
-                mSupervisor.getNextTaskId(), mStartActivity.info, mIntent, null, null, true);
+        final TaskRecord task = (prev != null) ? prev.task : mTargetStack.createTaskRecord(
+                        mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
+                        mStartActivity.info, mIntent, null, null, true);
         mStartActivity.setTask(task, null);
         mWindowManager.moveTaskToTop(mStartActivity.task.taskId);
         if (DEBUG_TASKS) Slog.v(TAG_TASKS,
@@ -1701,7 +1730,7 @@
             // and if yes, we will launch into that stack. If not, we just put the new
             // activity into parent's stack, because we can't find a better place.
             final ActivityStack stack = mSupervisor.getStack(DOCKED_STACK_ID);
-            if (stack != null && !stack.isStackVisibleLocked()) {
+            if (stack != null && stack.getStackVisibilityLocked() == STACK_INVISIBLE) {
                 // There is a docked stack, but it isn't visible, so we can't launch into that.
                 return null;
             } else {
@@ -1739,7 +1768,7 @@
         if (options != null && (r.isResizeable() || (inTask != null && inTask.mResizeable))) {
             if (mSupervisor.canUseActivityOptionsLaunchBounds(
                     options, options.getLaunchStackId())) {
-                newBounds = options.getLaunchBounds();
+                newBounds = TaskRecord.validateBounds(options.getLaunchBounds());
             }
         }
         return newBounds;
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/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 52d23cf..a3c26cb 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -16,7 +16,12 @@
 
 package com.android.server.am;
 
-import static com.android.server.am.ActivityManagerDebugConfig.*;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 
 import android.app.ActivityManager;
@@ -27,11 +32,16 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.os.Environment;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Slog;
+import android.util.SparseBooleanArray;
 
+import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -47,18 +57,106 @@
     // Maximum number recent bitmaps to keep in memory.
     private static final int MAX_RECENT_BITMAPS = 3;
 
-    // Activity manager service.
-    private final ActivityManagerService mService;
+    /**
+     * Save recent tasks information across reboots.
+     */
+    private final TaskPersister mTaskPersister;
+    private final SparseBooleanArray mUsersWithRecentsLoaded = new SparseBooleanArray(5);
 
     // Mainly to avoid object recreation on multiple calls.
     private final ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
-    private final HashMap<ComponentName, ActivityInfo> tmpAvailActCache = new HashMap<>();
-    private final HashMap<String, ApplicationInfo> tmpAvailAppCache = new HashMap<>();
-    private final ActivityInfo tmpActivityInfo = new ActivityInfo();
-    private final ApplicationInfo tmpAppInfo = new ApplicationInfo();
+    private final HashMap<ComponentName, ActivityInfo> mTmpAvailActCache = new HashMap<>();
+    private final HashMap<String, ApplicationInfo> mTmpAvailAppCache = new HashMap<>();
+    private final ActivityInfo mTmpActivityInfo = new ActivityInfo();
+    private final ApplicationInfo mTmpAppInfo = new ApplicationInfo();
 
-    RecentTasks(ActivityManagerService service) {
-        mService = service;
+    RecentTasks(ActivityManagerService service, ActivityStackSupervisor mStackSupervisor) {
+        File systemDir = Environment.getDataSystemDirectory();
+        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, service, this);
+        mStackSupervisor.setRecentTasks(this);
+    }
+
+    /**
+     * Loads the persistent recentTasks for {@code userId} into {@link #mRecentTasks} from
+     * persistent storage. Does nothing if they are already loaded.
+     *
+     * @param userId the user Id
+     */
+    void loadUserRecentsLocked(int userId) {
+        if (!mUsersWithRecentsLoaded.get(userId)) {
+            Slog.i(TAG, "Loading recents for user " + userId + " into memory.");
+            addAll(mTaskPersister.restoreTasksForUserLocked(userId));
+            cleanupLocked(userId);
+            mUsersWithRecentsLoaded.put(userId, true);
+        }
+    }
+
+    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
+        if (task != null && task.stack != null && task.stack.isHomeStack()) {
+            // Never persist the home stack.
+            return;
+        }
+        mTaskPersister.wakeup(task, flush);
+    }
+
+    void onSystemReady() {
+        clear();
+        loadUserRecentsLocked(UserHandle.USER_SYSTEM);
+        startPersisting();
+    }
+
+    void startPersisting() {
+        mTaskPersister.startPersisting();
+    }
+
+    Bitmap getTaskDescriptionIcon(String path) {
+        return mTaskPersister.getTaskDescriptionIcon(path);
+    }
+
+    Bitmap getImageFromWriteQueue(String path) {
+        return mTaskPersister.getImageFromWriteQueue(path);
+    }
+
+    void saveImage(Bitmap image, String path) {
+        mTaskPersister.saveImage(image, path);
+    }
+
+    void flush() {
+        mTaskPersister.flush();
+    }
+
+    /**
+     * Returns all userIds for which recents from storage are loaded
+     *
+     * @return an array of userIds.
+     */
+    int[] usersWithRecentsLoadedLocked() {
+        int[] usersWithRecentsLoaded = new int[mUsersWithRecentsLoaded.size()];
+        int len = 0;
+        for (int i = 0; i < usersWithRecentsLoaded.length; i++) {
+            int userId = mUsersWithRecentsLoaded.keyAt(i);
+            if (mUsersWithRecentsLoaded.valueAt(i)) {
+                usersWithRecentsLoaded[len++] = userId;
+            }
+        }
+        if (len < usersWithRecentsLoaded.length) {
+            // should never happen.
+            return Arrays.copyOf(usersWithRecentsLoaded, len);
+        }
+        return usersWithRecentsLoaded;
+    }
+
+    /**
+     * Removes recent tasks for this user if they are loaded, does not do anything otherwise.
+     *
+     * @param userId the user id.
+     */
+    void unloadUserRecentsLocked(int userId) {
+        if (mUsersWithRecentsLoaded.get(userId)) {
+            Slog.i(TAG, "Unloading recents for user " + userId + " from memory.");
+            mUsersWithRecentsLoaded.delete(userId);
+            removeTasksForUserLocked(userId);
+        }
     }
 
     TaskRecord taskForIdLocked(int id) {
@@ -88,9 +186,6 @@
                 tr.removedFromRecents();
             }
         }
-
-        // Remove tasks from persistent storage.
-        mService.notifyTaskPersisterLocked(null, true);
     }
 
     /**
@@ -107,87 +202,86 @@
         }
 
         final IPackageManager pm = AppGlobals.getPackageManager();
-        final int[] users = (userId == UserHandle.USER_ALL)
-                ? mService.mUserController.getUsers() : new int[] { userId };
-        for (int userIdx = 0; userIdx < users.length; userIdx++) {
-            final int user = users[userIdx];
-            recentsCount = size() - 1;
-            for (int i = recentsCount; i >= 0; i--) {
-                TaskRecord task = get(i);
-                if (task.userId != user) {
-                    // Only look at tasks for the user ID of interest.
-                    continue;
-                }
-                if (task.autoRemoveRecents && task.getTopActivity() == null) {
-                    // This situation is broken, and we should just get rid of it now.
-                    remove(i);
-                    task.removedFromRecents();
-                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
-                    continue;
-                }
-                // Check whether this activity is currently available.
-                if (task.realActivity != null) {
-                    ActivityInfo ai = tmpAvailActCache.get(task.realActivity);
+        for (int i = recentsCount - 1; i >= 0; i--) {
+            final TaskRecord task = get(i);
+            if (userId != UserHandle.USER_ALL && task.userId != userId) {
+                // Only look at tasks for the user ID of interest.
+                continue;
+            }
+            if (task.autoRemoveRecents && task.getTopActivity() == null) {
+                // This situation is broken, and we should just get rid of it now.
+                remove(i);
+                task.removedFromRecents();
+                Slog.w(TAG, "Removing auto-remove without activity: " + task);
+                continue;
+            }
+            // Check whether this activity is currently available.
+            if (task.realActivity != null) {
+                ActivityInfo ai = mTmpAvailActCache.get(task.realActivity);
+                if (ai == null) {
+                    try {
+                        // At this first cut, we're only interested in
+                        // activities that are fully runnable based on
+                        // current system state.
+                        ai = pm.getActivityInfo(task.realActivity,
+                                PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
+                    } catch (RemoteException e) {
+                        // Will never happen.
+                        continue;
+                    }
                     if (ai == null) {
+                        ai = mTmpActivityInfo;
+                    }
+                    mTmpAvailActCache.put(task.realActivity, ai);
+                }
+                if (ai == mTmpActivityInfo) {
+                    // This could be either because the activity no longer exists, or the
+                    // app is temporarily gone. For the former we want to remove the recents
+                    // entry; for the latter we want to mark it as unavailable.
+                    ApplicationInfo app = mTmpAvailAppCache
+                            .get(task.realActivity.getPackageName());
+                    if (app == null) {
                         try {
-                            // At this first cut, we're only interested in
-                            // activities that are fully runnable based on
-                            // current system state.
-                            ai = pm.getActivityInfo(task.realActivity,
-                                    PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user);
+                            app = pm.getApplicationInfo(task.realActivity.getPackageName(),
+                                    PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
                         } catch (RemoteException e) {
                             // Will never happen.
                             continue;
                         }
-                        if (ai == null) {
-                            ai = tmpActivityInfo;
-                        }
-                        tmpAvailActCache.put(task.realActivity, ai);
-                    }
-                    if (ai == tmpActivityInfo) {
-                        // This could be either because the activity no longer exists, or the
-                        // app is temporarily gone.  For the former we want to remove the recents
-                        // entry; for the latter we want to mark it as unavailable.
-                        ApplicationInfo app = tmpAvailAppCache.get(task.realActivity.getPackageName());
                         if (app == null) {
-                            try {
-                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
-                                        PackageManager.MATCH_UNINSTALLED_PACKAGES, user);
-                            } catch (RemoteException e) {
-                                // Will never happen.
-                                continue;
-                            }
-                            if (app == null) {
-                                app = tmpAppInfo;
-                            }
-                            tmpAvailAppCache.put(task.realActivity.getPackageName(), app);
+                            app = mTmpAppInfo;
                         }
-                        if (app == tmpAppInfo || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
-                            // Doesn't exist any more!  Good-bye.
-                            remove(i);
-                            task.removedFromRecents();
-                            Slog.w(TAG, "Removing no longer valid recent: " + task);
-                            continue;
-                        } else {
-                            // Otherwise just not available for now.
-                            if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS,
-                                    "Making recent unavailable: " + task);
-                            task.isAvailable = false;
-                        }
+                        mTmpAvailAppCache.put(task.realActivity.getPackageName(), app);
+                    }
+                    if (app == mTmpAppInfo
+                            || (app.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
+                        // Doesn't exist any more! Good-bye.
+                        remove(i);
+                        task.removedFromRecents();
+                        Slog.w(TAG, "Removing no longer valid recent: " + task);
+                        continue;
                     } else {
-                        if (!ai.enabled || !ai.applicationInfo.enabled
-                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
-                            if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS,
-                                    "Making recent unavailable: " + task
-                                    + " (enabled=" + ai.enabled + "/" + ai.applicationInfo.enabled
-                                    + " flags=" + Integer.toHexString(ai.applicationInfo.flags)
-                                    + ")");
-                            task.isAvailable = false;
-                        } else {
-                            if (DEBUG_RECENTS && !task.isAvailable) Slog.d(TAG_RECENTS,
-                                    "Making recent available: " + task);
-                            task.isAvailable = true;
-                        }
+                        // Otherwise just not available for now.
+                        if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS,
+                                "Making recent unavailable: " + task);
+                        task.isAvailable = false;
+                    }
+                } else {
+                    if (!ai.enabled || !ai.applicationInfo.enabled
+                            || (ai.applicationInfo.flags
+                                    & ApplicationInfo.FLAG_INSTALLED) == 0) {
+                        if (DEBUG_RECENTS && task.isAvailable) Slog.d(TAG_RECENTS,
+                                "Making recent unavailable: " + task
+                                        + " (enabled=" + ai.enabled + "/"
+                                        + ai.applicationInfo.enabled
+                                        + " flags="
+                                        + Integer.toHexString(ai.applicationInfo.flags)
+                                        + ")");
+                        task.isAvailable = false;
+                    } else {
+                        if (DEBUG_RECENTS && !task.isAvailable) Slog.d(TAG_RECENTS,
+                                "Making recent available: " + task);
+                        task.isAvailable = true;
                     }
                 }
             }
@@ -341,7 +435,7 @@
                     // Simple case: this is not an affiliated task, so we just move it to the front.
                     remove(taskIndex);
                     add(0, task);
-                    mService.notifyTaskPersisterLocked(task, false);
+                    notifyTaskPersisterLocked(task, false);
                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: moving to top " + task
                             + " from " + taskIndex);
                     return;
@@ -501,7 +595,7 @@
                 // specified, then replace it with the existing recent task.
                 task = tr;
             }
-            mService.notifyTaskPersisterLocked(tr, false);
+            notifyTaskPersisterLocked(tr, false);
         }
 
         return -1;
@@ -551,7 +645,7 @@
         if (first.mNextAffiliate != null) {
             Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
             first.setNextAffiliate(null);
-            mService.notifyTaskPersisterLocked(first, false);
+            notifyTaskPersisterLocked(first, false);
         }
         // Everything in the middle is doubly linked from next to prev.
         final int tmpSize = mTmpRecents.size();
@@ -562,13 +656,13 @@
                 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
                         " setting prev=" + prev);
                 next.setPrevAffiliate(prev);
-                mService.notifyTaskPersisterLocked(next, false);
+                notifyTaskPersisterLocked(next, false);
             }
             if (prev.mNextAffiliate != next) {
                 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
                         " setting next=" + next);
                 prev.setNextAffiliate(next);
-                mService.notifyTaskPersisterLocked(prev, false);
+                notifyTaskPersisterLocked(prev, false);
             }
             prev.inRecents = true;
         }
@@ -577,7 +671,7 @@
         if (last.mPrevAffiliate != null) {
             Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
             last.setPrevAffiliate(null);
-            mService.notifyTaskPersisterLocked(last, false);
+            notifyTaskPersisterLocked(last, false);
         }
 
         // Insert the group back into mRecentTasks at start.
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 9a00075..283939e 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -21,16 +21,18 @@
 import android.os.Debug;
 import android.os.Environment;
 import android.os.FileUtils;
+import android.os.Process;
 import android.os.SystemClock;
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.Xml;
-import android.os.Process;
 
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 
+import libcore.io.IoUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -42,12 +44,10 @@
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
-import libcore.io.IoUtils;
-
 public class TaskPersister {
     static final String TAG = "TaskPersister";
     static final boolean DEBUG = false;
@@ -113,7 +113,7 @@
     ArrayList<WriteQueueItem> mWriteQueue = new ArrayList<WriteQueueItem>();
 
     TaskPersister(File systemDir, ActivityStackSupervisor stackSupervisor,
-            RecentTasks recentTasks) {
+            ActivityManagerService service, RecentTasks recentTasks) {
 
         final File legacyImagesDir = new File(systemDir, IMAGES_DIRNAME);
         if (legacyImagesDir.exists()) {
@@ -130,7 +130,7 @@
         }
 
         mStackSupervisor = stackSupervisor;
-        mService = stackSupervisor.mService;
+        mService = service;
         mRecentTasks = recentTasks;
         mLazyTaskWriterThread = new LazyTaskWriterThread("LazyTaskWriterThread");
     }
@@ -145,11 +145,15 @@
         final String taskString = Integer.toString(task.taskId);
         for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
             final WriteQueueItem item = mWriteQueue.get(queueNdx);
-            if (item instanceof ImageWriteQueueItem &&
-                    ((ImageWriteQueueItem) item).mFilePath.startsWith(taskString)) {
-                if (DEBUG) Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilePath +
-                        " from write queue");
-                mWriteQueue.remove(queueNdx);
+            if (item instanceof ImageWriteQueueItem) {
+                final File thumbnailFile = new File(((ImageWriteQueueItem) item).mFilePath);
+                if (thumbnailFile.getName().startsWith(taskString)) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilePath +
+                                " from write queue");
+                    }
+                    mWriteQueue.remove(queueNdx);
+                }
             }
         }
     }
@@ -185,7 +189,8 @@
                     mWriteQueue.add(new TaskWriteQueueItem(task));
                 }
             } else {
-                // Dummy.
+                // Dummy. Ensures removeObsoleteFiles is called when LazyTaskThreadWriter is
+                // notified.
                 mWriteQueue.add(new WriteQueueItem());
             }
             if (flush || mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) {
@@ -323,8 +328,8 @@
         return null;
     }
 
-    private List<TaskRecord> restoreTasksForUserLocked(final int userId) {
-        final List<TaskRecord> tasks = new ArrayList<TaskRecord>();
+    List<TaskRecord> restoreTasksForUserLocked(final int userId) {
+        final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>();
         ArraySet<Integer> recoveredTaskIds = new ArraySet<Integer>();
 
         File userTasksDir = getUserTasksDir(userId);
@@ -351,10 +356,10 @@
                         event != XmlPullParser.END_TAG) {
                     final String name = in.getName();
                     if (event == XmlPullParser.START_TAG) {
-                        if (DEBUG) Slog.d(TAG, "restoreTasksLocked: START_TAG name=" + name);
+                        if (DEBUG) Slog.d(TAG, "restoreTasksForUserLocked: START_TAG name=" + name);
                         if (TAG_TASK.equals(name)) {
                             final TaskRecord task = TaskRecord.restoreFromXml(in, mStackSupervisor);
-                            if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task="
+                            if (DEBUG) Slog.d(TAG, "restoreTasksForUserLocked: restored task="
                                     + task);
                             if (task != null) {
                                 // XXX Don't add to write queue... there is no reason to write
@@ -362,7 +367,7 @@
                                 // read the same thing again.
                                 // mWriteQueue.add(new TaskWriteQueueItem(task));
                                 final int taskId = task.taskId;
-                                mStackSupervisor.setNextTaskId(taskId);
+                                mStackSupervisor.setNextTaskIdForUserLocked(taskId, userId);
                                 // Check if it's a valid user id. Don't add tasks for removed users.
                                 if (userId == task.userId) {
                                     task.isPersistable = true;
@@ -396,15 +401,6 @@
         if (!DEBUG) {
             removeObsoleteFiles(recoveredTaskIds, userTasksDir.listFiles());
         }
-        return tasks;
-    }
-
-    ArrayList<TaskRecord> restoreTasksLocked(final int[] validUserIds) {
-        final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>();
-
-        for (int userId : validUserIds) {
-            tasks.addAll(restoreTasksForUserLocked(userId));
-        }
 
         // Fix up task affiliation from taskIds
         for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -413,9 +409,7 @@
             task.setNextAffiliate(taskIdToTask(task.mNextAffiliateTaskId, tasks));
         }
 
-        TaskRecord[] tasksArray = new TaskRecord[tasks.size()];
-        tasks.toArray(tasksArray);
-        Arrays.sort(tasksArray, new Comparator<TaskRecord>() {
+        Collections.sort(tasks, new Comparator<TaskRecord>() {
             @Override
             public int compare(TaskRecord lhs, TaskRecord rhs) {
                 final long diff = rhs.mLastTimeMoved - lhs.mLastTimeMoved;
@@ -428,8 +422,7 @@
                 }
             }
         });
-
-        return new ArrayList<TaskRecord>(Arrays.asList(tasksArray));
+        return tasks;
     }
 
     private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) {
@@ -462,7 +455,13 @@
     }
 
     private void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds) {
-        for (int userId : mService.getRunningUserIds()) {
+        int[] candidateUserIds;
+        synchronized (mService) {
+            // Remove only from directories of the users who have recents in memory synchronized
+            // with persistent storage.
+            candidateUserIds = mRecentTasks.usersWithRecentsLoadedLocked();
+        }
+        for (int userId : candidateUserIds) {
             removeObsoleteFiles(persistentTaskIds, getUserImagesDir(userId).listFiles());
             removeObsoleteFiles(persistentTaskIds, getUserTasksDir(userId).listFiles());
         }
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ae987e6..cc86a62 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
@@ -205,7 +206,7 @@
 
     // Used in the unique case where we are clearing the task in order to reuse it. In that case we
     // do not want to delete the stack when the task goes empty.
-    boolean mReuseTask = false;
+    private boolean mReuseTask = false;
 
     private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
     private final File mLastThumbnailFile; // File containing last thumbnail.
@@ -551,7 +552,7 @@
                     mLastThumbnailFile.delete();
                 }
             } else {
-                mService.mTaskPersister.saveImage(thumbnail, mLastThumbnailFile.getAbsolutePath());
+                mService.mRecentTasks.saveImage(thumbnail, mLastThumbnailFile.getAbsolutePath());
             }
             return true;
         }
@@ -563,7 +564,7 @@
         thumbs.thumbnailInfo = mLastThumbnailInfo;
         thumbs.thumbnailFileDescriptor = null;
         if (mLastThumbnail == null) {
-            thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(
+            thumbs.mainThumbnail = mService.mRecentTasks.getImageFromWriteQueue(
                     mLastThumbnailFile.getAbsolutePath());
         }
         // Only load the thumbnail file if we don't have a thumbnail
@@ -774,6 +775,13 @@
         mReuseTask = false;
     }
 
+    ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
+        mReuseTask = true;
+        final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
+        mReuseTask = false;
+        return result;
+    }
+
     /**
      * Perform clear operation as requested by
      * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
@@ -1310,6 +1318,20 @@
         return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
     }
 
+    Rect updateOverrideConfigurationFromLaunchBounds() {
+        final Rect bounds = validateBounds(getLaunchBounds());
+        updateOverrideConfiguration(bounds);
+        return bounds;
+    }
+
+    static Rect validateBounds(Rect bounds) {
+        if (bounds != null && bounds.isEmpty()) {
+            Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
+            return null;
+        }
+        return bounds;
+    }
+
     private void reportMultiWindowModeChange() {
         for (int i = mActivities.size() - 1; i >= 0; i--) {
             final ActivityRecord r = mActivities.get(i);
@@ -1386,17 +1408,20 @@
 
     /** Returns the bounds that should be used to launch this task. */
     Rect getLaunchBounds() {
-        final int stackId = stack.mStackId;
-
         // If we're over lockscreen, forget about stack bounds and use fullscreen.
         if (mService.mLockScreenShown == LOCK_SCREEN_SHOWN) {
             return null;
         }
 
-        if (stack == null
-                || stackId == HOME_STACK_ID
-                || stackId == FULLSCREEN_WORKSPACE_STACK_ID) {
-            return (mResizeable && stack != null) ? stack.mBounds : null;
+        if (stack == null) {
+            return null;
+        }
+
+        final int stackId = stack.mStackId;
+        if (stackId == HOME_STACK_ID
+                || stackId == FULLSCREEN_WORKSPACE_STACK_ID
+                || (stackId == DOCKED_STACK_ID && !mResizeable)) {
+            return mResizeable ? stack.mBounds : null;
         } else if (!StackId.persistTaskBounds(stackId)) {
             return stack.mBounds;
         }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 7172859..8c16872 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -143,6 +143,8 @@
 
     private volatile UserManagerService mUserManager;
 
+    private final LockPatternUtils mLockPatternUtils;
+
     UserController(ActivityManagerService service) {
         mService = service;
         mHandler = mService.mHandler;
@@ -150,6 +152,7 @@
         final UserState uss = new UserState(UserHandle.SYSTEM);
         mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
         mUserLru.add(UserHandle.USER_SYSTEM);
+        mLockPatternUtils = new LockPatternUtils(mService.mContext);
         updateStartedUserArrayLocked();
     }
 
@@ -246,6 +249,9 @@
             if (uss.state == UserState.STATE_RUNNING_LOCKED) {
                 uss.setState(UserState.STATE_RUNNING);
 
+                // Give user manager a chance to prepare app storage
+                mUserManager.onBeforeUnlockUser(userId);
+
                 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
 
                 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
@@ -419,6 +425,7 @@
                 mUserLru.remove(Integer.valueOf(userId));
                 updateStartedUserArrayLocked();
 
+                mService.onUserStoppedLocked(userId);
                 // Clean up all state and processes associated with the user.
                 // Kill all the processes for the user.
                 forceStopUserLocked(userId, "finish user");
@@ -648,7 +655,8 @@
                 }
 
                 if (uss.state == UserState.STATE_BOOTING) {
-                    // Let user manager propagate user restrictions to other services.
+                    // Give user manager a chance to propagate user restrictions
+                    // to other services and prepare app storage
                     getUserManager().onBeforeStartUser(userId);
 
                     // Booting up a new user, need to tell system services about it.
@@ -1121,8 +1129,7 @@
             UserState uss = mStartedUsers.valueAt(i);
             if (uss.state != UserState.STATE_STOPPING
                     && uss.state != UserState.STATE_SHUTDOWN) {
-                mStartedUserArray[num] = mStartedUsers.keyAt(i);
-                num++;
+                mStartedUserArray[num++] = mStartedUsers.keyAt(i);
             }
         }
     }
@@ -1294,13 +1301,12 @@
      * intercept activity launches for work apps when the Work Challenge is present.
      */
     boolean shouldConfirmCredentials(int userId) {
-        final UserInfo user = getUserInfo(userId);
-        if (!user.isManagedProfile() || !LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
             return false;
         }
         final KeyguardManager km = (KeyguardManager) mService.mContext
                 .getSystemService(KEYGUARD_SERVICE);
-        return km.isDeviceLocked(user.id);
+        return km.isDeviceLocked(userId);
     }
 
     void dump(PrintWriter pw, boolean dumpAll) {
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/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 5bd4f98..fd9abff 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -63,6 +63,7 @@
 import android.os.SystemService;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.security.Credentials;
 import android.security.KeyStore;
 import android.text.TextUtils;
@@ -169,6 +170,58 @@
     }
 
     /**
+     * Configures an always-on VPN connection through a specific application.
+     * This connection is automatically granted and persisted after a reboot.
+     *
+     * <p>The designated package should exist and declare a {@link VpnService} in its
+     *    manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
+     *    otherwise the call will fail.
+     *
+     * @param newPackage the package to designate as always-on VPN supplier.
+     */
+    public synchronized boolean setAlwaysOnPackage(String packageName) {
+        enforceControlPermissionOrInternalCaller();
+
+        // Disconnect current VPN.
+        prepareInternal(VpnConfig.LEGACY_VPN);
+
+        // Pre-authorize new always-on VPN package.
+        if (packageName != null) {
+            if (!setPackageAuthorization(packageName, true)) {
+                return false;
+            }
+        }
+
+        // Save the new package name in Settings.Secure.
+        final long token = Binder.clearCallingIdentity();
+        try {
+            Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                    Settings.Secure.ALWAYS_ON_VPN_APP, packageName, mUserHandle);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return true;
+    }
+
+    /**
+     * @return the package name of the VPN controller responsible for always-on VPN,
+     *         or {@code null} if none is set or always-on VPN is controlled through
+     *         lockdown instead.
+     * @hide
+     */
+    public synchronized String getAlwaysOnPackage() {
+        enforceControlPermissionOrInternalCaller();
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                    Settings.Secure.ALWAYS_ON_VPN_APP, mUserHandle);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
      * Prepare for a VPN application. This method is designed to solve
      * race conditions. It first compares the current prepared package
      * with {@code oldPackage}. If they are the same, the prepared
@@ -270,14 +323,14 @@
     /**
      * Set whether a package has the ability to launch VPNs without user intervention.
      */
-    public void setPackageAuthorization(String packageName, boolean authorized) {
+    public boolean setPackageAuthorization(String packageName, boolean authorized) {
         // Check if the caller is authorized.
-        enforceControlPermission();
+        enforceControlPermissionOrInternalCaller();
 
         int uid = getAppUid(packageName, mUserHandle);
         if (uid == -1 || VpnConfig.LEGACY_VPN.equals(packageName)) {
             // Authorization for nonexistent packages (or fake ones) can't be updated.
-            return;
+            return false;
         }
 
         long token = Binder.clearCallingIdentity();
@@ -286,11 +339,13 @@
                     (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
             appOps.setMode(AppOpsManager.OP_ACTIVATE_VPN, uid, packageName,
                     authorized ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
+            return true;
         } catch (Exception e) {
             Log.wtf(TAG, "Failed to set app ops for package " + packageName + ", uid " + uid, e);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
+        return false;
     }
 
     private boolean isVpnUserPreConsented(String packageName) {
@@ -743,6 +798,13 @@
         mContext.enforceCallingPermission(Manifest.permission.CONTROL_VPN, "Unauthorized Caller");
     }
 
+    private void enforceControlPermissionOrInternalCaller() {
+        // Require caller to be either an application with CONTROL_VPN permission or a process
+        // in the system server.
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONTROL_VPN,
+                "Unauthorized Caller");
+    }
+
     private class Connection implements ServiceConnection {
         private IBinder mService;
 
@@ -882,9 +944,6 @@
      */
     public void startLegacyVpnPrivileged(VpnProfile profile, KeyStore keyStore,
             LinkProperties egress) {
-        if (!keyStore.isUnlocked()) {
-            throw new IllegalStateException("KeyStore isn't unlocked");
-        }
         UserManager mgr = UserManager.get(mContext);
         UserInfo user = mgr.getUserInfo(mUserHandle);
         if (user.isRestricted() || mgr.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN,
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/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 78618ce..2eb9095 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -2682,6 +2682,31 @@
                         }
                         continue;
                     }
+                    String packageName = getPackageName(op.target);
+                    ApplicationInfo ai = null;
+                    if (packageName != null) {
+                        try {
+                            ai = mContext.getPackageManager().getApplicationInfo(packageName,
+                                    PackageManager.GET_UNINSTALLED_PACKAGES
+                                            | PackageManager.GET_DISABLED_COMPONENTS);
+                        } catch (NameNotFoundException e) {
+                            operationIterator.remove();
+                            mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+                            continue;
+                        }
+                    }
+                    // If app is considered idle, then skip for now and backoff
+                    if (ai != null
+                            && mAppIdleMonitor.isAppIdle(packageName, ai.uid, op.target.userId)) {
+                        increaseBackoffSetting(op);
+                        op.appIdle = true;
+                        if (isLoggable) {
+                            Log.v(TAG, "Sync backing off idle app " + packageName);
+                        }
+                        continue;
+                    } else {
+                        op.appIdle = false;
+                    }
                     if (!isOperationValidLocked(op)) {
                         operationIterator.remove();
                         mSyncStorageEngine.deleteFromPending(op.pendingOperation);
@@ -2700,28 +2725,6 @@
                         }
                         continue;
                     }
-                    String packageName = getPackageName(op.target);
-                    ApplicationInfo ai = null;
-                    if (packageName != null) {
-                        try {
-                            ai = mContext.getPackageManager().getApplicationInfo(packageName,
-                                    PackageManager.GET_UNINSTALLED_PACKAGES
-                                    | PackageManager.GET_DISABLED_COMPONENTS);
-                        } catch (NameNotFoundException e) {
-                        }
-                    }
-                    // If app is considered idle, then skip for now and backoff
-                    if (ai != null
-                            && mAppIdleMonitor.isAppIdle(packageName, ai.uid, op.target.userId)) {
-                        increaseBackoffSetting(op);
-                        op.appIdle = true;
-                        if (isLoggable) {
-                            Log.v(TAG, "Sync backing off idle app " + packageName);
-                        }
-                        continue;
-                    } else {
-                        op.appIdle = false;
-                    }
                     // Add this sync to be run.
                     operations.add(op);
                 }
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 8266c08..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;
         }
@@ -1903,8 +1911,10 @@
                             if ("authority".equals(tagName)) {
                                 authority = parseAuthority(parser, version);
                                 periodicSync = null;
-                                if (authority.ident > highestAuthorityId) {
-                                    highestAuthorityId = authority.ident;
+                                if (authority != null) {
+                                    if (authority.ident > highestAuthorityId) {
+                                        highestAuthorityId = authority.ident;
+                                    }
                                 }
                             } else if (XML_TAG_LISTEN_FOR_TICKLES.equals(tagName)) {
                                 parseListenForTickles(parser);
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index 835ba17..a16fcd2 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -587,16 +587,16 @@
                     Slog.e(TAG, "Unable to create surface.", ex);
                     return false;
                 }
+
+                mSurfaceControl.setLayerStack(mDisplayLayerStack);
+                mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight);
+                mSurface = new Surface();
+                mSurface.copyFrom(mSurfaceControl);
+
+                mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal,
+                        mDisplayId, mSurfaceControl);
+                mSurfaceLayout.onDisplayTransaction();
             }
-
-            mSurfaceControl.setLayerStack(mDisplayLayerStack);
-            mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight);
-            mSurface = new Surface();
-            mSurface.copyFrom(mSurfaceControl);
-
-            mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal,
-                    mDisplayId, mSurfaceControl);
-            mSurfaceLayout.onDisplayTransaction();
         } finally {
             SurfaceControl.closeTransaction();
         }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 433d887..b74b0f2 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -673,6 +673,9 @@
                 slowChange = false;
             }
             mAppliedDimming = true;
+        } else if (mAppliedDimming) {
+            slowChange = false;
+            mAppliedDimming = false;
         }
 
         // If low power mode is enabled, cut the brightness level by half
@@ -685,6 +688,9 @@
                 slowChange = false;
             }
             mAppliedLowPower = true;
+        } else if (mAppliedLowPower) {
+            slowChange = false;
+            mAppliedLowPower = false;
         }
 
         // Animate the screen brightness when the screen is on or dozing.
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 3530d80..c63ce73 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -16,14 +16,21 @@
 
 package com.android.server.job;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IUidObserver;
-import android.app.job.IJobScheduler;
 import android.app.job.JobInfo;
+import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
 import android.app.job.JobService;
+import android.app.job.IJobScheduler;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -42,12 +49,12 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.Process;
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.app.IBatteryStats;
-import com.android.internal.util.ArrayUtils;
 import com.android.server.DeviceIdleController;
 import com.android.server.LocalServices;
 import com.android.server.job.controllers.AppIdleController;
@@ -58,15 +65,6 @@
 import com.android.server.job.controllers.StateController;
 import com.android.server.job.controllers.TimeController;
 
-import libcore.util.EmptyArray;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
 /**
  * Responsible for taking jobs representing work to be performed by a client app, and determining
  * based on the criteria specified when that job should be run against the client application's
@@ -130,7 +128,7 @@
      */
     final ArrayList<JobStatus> mPendingJobs = new ArrayList<>();
 
-    int[] mStartedUsers = EmptyArray.INT;
+    final ArrayList<Integer> mStartedUsers = new ArrayList<>();
 
     final JobHandler mHandler;
     final JobSchedulerStub mJobSchedulerStub;
@@ -161,9 +159,8 @@
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            Slog.d(TAG, "Receieved: " + action);
-            if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+            Slog.d(TAG, "Receieved: " + intent.getAction());
+            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
                 // If this is an outright uninstall rather than the first half of an
                 // app update sequence, cancel the jobs associated with the app.
                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
@@ -173,21 +170,18 @@
                     }
                     cancelJobsForUid(uidRemoved, true);
                 }
-            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                 if (DEBUG) {
                     Slog.d(TAG, "Removing jobs for user: " + userId);
                 }
                 cancelJobsForUser(userId);
-            } else if (PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED.equals(action)
-                    || PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
+            } else if (PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())
+                    || PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(intent.getAction())) {
                 updateIdleMode(mPowerManager != null
                         ? (mPowerManager.isDeviceIdleMode()
-                                || mPowerManager.isLightDeviceIdleMode())
+                        || mPowerManager.isLightDeviceIdleMode())
                         : false);
-            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
-                // Kick off pending jobs for any apps that re-appeared
-                mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
             }
         }
     };
@@ -209,20 +203,14 @@
 
     @Override
     public void onStartUser(int userHandle) {
-        mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userHandle);
-        // Let's kick any outstanding jobs for this user.
-        mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
-    }
-
-    @Override
-    public void onUnlockUser(int userHandle) {
+        mStartedUsers.add(userHandle);
         // Let's kick any outstanding jobs for this user.
         mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
     }
 
     @Override
     public void onStopUser(int userHandle) {
-        mStartedUsers = ArrayUtils.removeInt(mStartedUsers, userHandle);
+        mStartedUsers.remove(Integer.valueOf(userHandle));
     }
 
     /**
@@ -233,7 +221,14 @@
      * @return Result of this operation. See <code>JobScheduler#RESULT_*</code> return codes.
      */
     public int schedule(JobInfo job, int uId) {
+        return scheduleAsPackage(job, uId, null, -1);
+    }
+
+    public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId) {
         JobStatus jobStatus = new JobStatus(job, uId);
+        if (packageName != null) {
+            jobStatus.setSource(packageName, userId);
+        }
         cancelJob(uId, job.getId());
         try {
             if (ActivityManagerNative.getDefault().getAppStartMode(uId,
@@ -329,7 +324,7 @@
             // Remove from pending queue.
             mPendingJobs.remove(cancelled);
             // Cancel if running.
-            stopJobOnServiceContextLocked(cancelled);
+            stopJobOnServiceContextLocked(cancelled, JobParameters.REASON_CANCELED);
             reportActive();
         }
     }
@@ -357,7 +352,7 @@
                         JobServiceContext jsc = mActiveServices.get(i);
                         final JobStatus executing = jsc.getRunningJob();
                         if (executing != null) {
-                            jsc.cancelExecutingJob();
+                            jsc.cancelExecutingJob(JobParameters.REASON_DEVICE_IDLE);
                         }
                     }
                 } else {
@@ -382,7 +377,7 @@
         if (mPendingJobs.size() <= 0) {
             for (int i=0; i<mActiveServices.size(); i++) {
                 JobServiceContext jsc = mActiveServices.get(i);
-                if (!jsc.isAvailable()) {
+                if (jsc.getRunningJob() != null) {
                     active = true;
                     break;
                 }
@@ -429,24 +424,17 @@
     @Override
     public void onBootPhase(int phase) {
         if (PHASE_SYSTEM_SERVICES_READY == phase) {
-            // Register for package removals and user removals.
+            // Register br for package removals and user removals.
             final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
             filter.addDataScheme("package");
             getContext().registerReceiverAsUser(
                     mBroadcastReceiver, UserHandle.ALL, filter, null, null);
-
             final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED);
             userFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
             userFilter.addAction(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
             getContext().registerReceiverAsUser(
                     mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);
-
-            final IntentFilter storageFilter = new IntentFilter();
-            storageFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
-            getContext().registerReceiverAsUser(
-                    mBroadcastReceiver, UserHandle.ALL, storageFilter, null, null);
-
-            mPowerManager = getContext().getSystemService(PowerManager.class);
+            mPowerManager = (PowerManager)getContext().getSystemService(Context.POWER_SERVICE);
             try {
                 ActivityManagerNative.getDefault().registerUidObserver(mUidObserver,
                         ActivityManager.UID_OBSERVER_IDLE);
@@ -526,12 +514,12 @@
         return removed;
     }
 
-    private boolean stopJobOnServiceContextLocked(JobStatus job) {
+    private boolean stopJobOnServiceContextLocked(JobStatus job, int reason) {
         for (int i=0; i<mActiveServices.size(); i++) {
             JobServiceContext jsc = mActiveServices.get(i);
             final JobStatus executing = jsc.getRunningJob();
             if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
-                jsc.cancelExecutingJob();
+                jsc.cancelExecutingJob(reason);
                 return true;
             }
         }
@@ -731,6 +719,7 @@
          */
         private void queueReadyJobsForExecutionLockedH() {
             ArraySet<JobStatus> jobs = mJobs.getJobs();
+            mPendingJobs.clear();
             if (DEBUG) {
                 Slog.d(TAG, "queuing all ready jobs for execution:");
             }
@@ -741,8 +730,9 @@
                         Slog.d(TAG, "    queued " + job.toShortString());
                     }
                     mPendingJobs.add(job);
-                } else if (isReadyToBeCancelledLocked(job)) {
-                    stopJobOnServiceContextLocked(job);
+                } else if (areJobConstraintsNotSatisfied(job)) {
+                    stopJobOnServiceContextLocked(job,
+                            JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
                 }
             }
             if (DEBUG) {
@@ -765,8 +755,9 @@
          * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
          */
         private void maybeQueueReadyJobsForExecutionLockedH() {
+            mPendingJobs.clear();
             int chargingCount = 0;
-            int idleCount = 0;
+            int idleCount =  0;
             int backoffCount = 0;
             int connectivityCount = 0;
             List<JobStatus> runnableJobs = null;
@@ -801,8 +792,9 @@
                         runnableJobs = new ArrayList<>();
                     }
                     runnableJobs.add(job);
-                } else if (isReadyToBeCancelledLocked(job)) {
-                    stopJobOnServiceContextLocked(job);
+                } else if (areJobConstraintsNotSatisfied(job)) {
+                    stopJobOnServiceContextLocked(job,
+                            JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
                 }
             }
             if (backoffCount > 0 ||
@@ -821,11 +813,6 @@
                     Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Not running anything.");
                 }
             }
-            if (DEBUG) {
-                Slog.d(TAG, "idle=" + idleCount + " connectivity=" +
-                connectivityCount + " charging=" + chargingCount + " tot=" +
-                        runnableJobs.size());
-            }
         }
 
         /**
@@ -834,31 +821,18 @@
          *      - It's not pending.
          *      - It's not already running on a JSC.
          *      - The user that requested the job is running.
-         *      - The component is enabled and runnable.
          */
         private boolean isReadyToBeExecutedLocked(JobStatus job) {
             final boolean jobReady = job.isReady();
             final boolean jobPending = mPendingJobs.contains(job);
             final boolean jobActive = isCurrentlyActiveLocked(job);
-
-            final int userId = job.getUserId();
-            final boolean userStarted = ArrayUtils.contains(mStartedUsers, userId);
-            final boolean componentPresent;
-            try {
-                componentPresent = (AppGlobals.getPackageManager().getServiceInfo(
-                        job.getServiceComponent(), PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
-                        userId) != null);
-            } catch (RemoteException e) {
-                throw e.rethrowAsRuntimeException();
-            }
-
+            final boolean userRunning = mStartedUsers.contains(job.getUserId());
             if (DEBUG) {
                 Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
                         + " ready=" + jobReady + " pending=" + jobPending
-                        + " active=" + jobActive + " userStarted=" + userStarted
-                        + " componentPresent=" + componentPresent);
+                        + " active=" + jobActive + " userRunning=" + userRunning);
             }
-            return userStarted && componentPresent && jobReady && !jobPending && !jobActive;
+            return userRunning && jobReady && !jobPending && !jobActive;
         }
 
         /**
@@ -866,7 +840,7 @@
          *      - It's not ready
          *      - It's running on a JSC.
          */
-        private boolean isReadyToBeCancelledLocked(JobStatus job) {
+        private boolean areJobConstraintsNotSatisfied(JobStatus job) {
             return !job.isReady() && isCurrentlyActiveLocked(job);
         }
 
@@ -881,46 +855,126 @@
                     // If device is idle, we will not schedule jobs to run.
                     return;
                 }
-                Iterator<JobStatus> it = mPendingJobs.iterator();
                 if (DEBUG) {
                     Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs.");
                 }
-                while (it.hasNext()) {
-                    JobStatus nextPending = it.next();
-                    JobServiceContext availableContext = null;
-                    for (int i=0; i<mActiveServices.size(); i++) {
-                        JobServiceContext jsc = mActiveServices.get(i);
-                        final JobStatus running = jsc.getRunningJob();
-                        if (running != null && running.matches(nextPending.getUid(),
-                                nextPending.getJobId())) {
-                            // Already running this job for this uId, skip.
-                            availableContext = null;
-                            break;
-                        }
-                        if (jsc.isAvailable()) {
-                            availableContext = jsc;
-                        }
-                    }
-                    if (availableContext != null) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "About to run job "
-                                    + nextPending.getJob().getService().toString());
-                        }
-                        if (!availableContext.executeRunnableJob(nextPending)) {
-                            if (DEBUG) {
-                                Slog.d(TAG, "Error executing " + nextPending);
-                            }
-                            mJobs.remove(nextPending);
-                        }
-                        it.remove();
-                    }
-                }
+                assignJobsToContextsH();
                 reportActive();
             }
         }
     }
 
     /**
+     * Takes jobs from pending queue and runs them on available contexts.
+     * If no contexts are available, preempts lower priority jobs to
+     * run higher priority ones.
+     * Lock on mJobs before calling this function.
+     */
+    private void assignJobsToContextsH() {
+        if (DEBUG) {
+            Slog.d(TAG, printPendingQueue());
+        }
+
+        // This array essentially stores the state of mActiveServices array.
+        // ith index stores the job present on the ith JobServiceContext.
+        // We manipulate this array until we arrive at what jobs should be running on
+        // what JobServiceContext.
+        JobStatus[] contextIdToJobMap = new JobStatus[MAX_JOB_CONTEXTS_COUNT];
+        // Indicates whether we need to act on this jobContext id
+        boolean[] act = new boolean[MAX_JOB_CONTEXTS_COUNT];
+        int[] preferredUidForContext = new int[MAX_JOB_CONTEXTS_COUNT];
+        for (int i=0; i<mActiveServices.size(); i++) {
+            contextIdToJobMap[i] = mActiveServices.get(i).getRunningJob();
+            preferredUidForContext[i] = mActiveServices.get(i).getPreferredUid();
+        }
+        if (DEBUG) {
+            Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs initial"));
+        }
+        Iterator<JobStatus> it = mPendingJobs.iterator();
+        while (it.hasNext()) {
+            JobStatus nextPending = it.next();
+
+            // If job is already running, go to next job.
+            int jobRunningContext = findJobContextIdFromMap(nextPending, contextIdToJobMap);
+            if (jobRunningContext != -1) {
+                continue;
+            }
+
+            // Find a context for nextPending. The context should be available OR
+            // it should have lowest priority among all running jobs
+            // (sharing the same Uid as nextPending)
+            int minPriority = Integer.MAX_VALUE;
+            int minPriorityContextId = -1;
+            for (int i=0; i<mActiveServices.size(); i++) {
+                JobStatus job = contextIdToJobMap[i];
+                int preferredUid = preferredUidForContext[i];
+                if (job == null && (preferredUid == nextPending.getUid() ||
+                        preferredUid == JobServiceContext.NO_PREFERRED_UID) ) {
+                    minPriorityContextId = i;
+                    break;
+                }
+                if (job == null) {
+                    // No job on this context, but nextPending can't run here because
+                    // the context has a preferred Uid.
+                    continue;
+                }
+                if (job.getUid() != nextPending.getUid()) {
+                    continue;
+                }
+                if (job.getPriority() >= nextPending.getPriority()) {
+                    continue;
+                }
+                if (minPriority > nextPending.getPriority()) {
+                    minPriority = nextPending.getPriority();
+                    minPriorityContextId = i;
+                }
+            }
+            if (minPriorityContextId != -1) {
+                contextIdToJobMap[minPriorityContextId] = nextPending;
+                act[minPriorityContextId] = true;
+            }
+        }
+        if (DEBUG) {
+            Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs final"));
+        }
+        for (int i=0; i<mActiveServices.size(); i++) {
+            boolean preservePreferredUid = false;
+            if (act[i]) {
+                JobStatus js = mActiveServices.get(i).getRunningJob();
+                if (js != null) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "preempting job: " + mActiveServices.get(i).getRunningJob());
+                    }
+                    // preferredUid will be set to uid of currently running job.
+                    mActiveServices.get(i).preemptExecutingJob();
+                    preservePreferredUid = true;
+                } else {
+                    if (DEBUG) {
+                        Slog.d(TAG, "About to run job on context "
+                                + String.valueOf(i) + ", job: " + contextIdToJobMap[i]);
+                    }
+                    if (!mActiveServices.get(i).executeRunnableJob(contextIdToJobMap[i])) {
+                        Slog.d(TAG, "Error executing " + contextIdToJobMap[i]);
+                    }
+                    mPendingJobs.remove(contextIdToJobMap[i]);
+                }
+            }
+            if (!preservePreferredUid) {
+                mActiveServices.get(i).clearPreferredUid();
+            }
+        }
+    }
+
+    int findJobContextIdFromMap(JobStatus jobStatus, JobStatus[] map) {
+        for (int i=0; i<map.length; i++) {
+            if (map[i] != null && map[i].matches(jobStatus.getUid(), jobStatus.getJobId())) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
      * Binder stub trampoline implementation
      */
     final class JobSchedulerStub extends IJobScheduler.Stub {
@@ -936,8 +990,7 @@
             final IPackageManager pm = AppGlobals.getPackageManager();
             final ComponentName service = job.getService();
             try {
-                ServiceInfo si = pm.getServiceInfo(service,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(uid));
+                ServiceInfo si = pm.getServiceInfo(service, 0, UserHandle.getUserId(uid));
                 if (si == null) {
                     throw new IllegalArgumentException("No such service " + service);
                 }
@@ -1001,6 +1054,25 @@
         }
 
         @Override
+        public int scheduleAsPackage(JobInfo job, String packageName, int userId)
+                throws RemoteException {
+            if (DEBUG) {
+                Slog.d(TAG, "Scheduling job: " + job.toString() + " on behalf of " + packageName);
+            }
+            final int uid = Binder.getCallingUid();
+            if (uid != Process.SYSTEM_UID) {
+                throw new IllegalArgumentException("Only system process is allowed"
+                        + "to set packageName");
+            }
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return JobSchedulerService.this.scheduleAsPackage(job, uid, packageName, userId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
         public List<JobInfo> getAllPendingJobs() throws RemoteException {
             final int uid = Binder.getCallingUid();
 
@@ -1050,12 +1122,41 @@
                 Binder.restoreCallingIdentity(identityToken);
             }
         }
+    };
+
+    private String printContextIdToJobMap(JobStatus[] map, String initial) {
+        StringBuilder s = new StringBuilder(initial + ": ");
+        for (int i=0; i<map.length; i++) {
+            s.append("(")
+                    .append(map[i] == null? -1: map[i].getJobId())
+                    .append(map[i] == null? -1: map[i].getUid())
+                    .append(")" );
+        }
+        return s.toString();
+    }
+
+    private String printPendingQueue() {
+        StringBuilder s = new StringBuilder("Pending queue: ");
+        Iterator<JobStatus> it = mPendingJobs.iterator();
+        while (it.hasNext()) {
+            JobStatus js = it.next();
+            s.append("(")
+                    .append(js.getJob().getId())
+                    .append(", ")
+                    .append(js.getUid())
+                    .append(") ");
+        }
+        return s.toString();
     }
 
     void dumpInternal(PrintWriter pw) {
         final long now = SystemClock.elapsedRealtime();
         synchronized (mJobs) {
-            pw.println("Started users: " + Arrays.toString(mStartedUsers));
+            pw.print("Started users: ");
+            for (int i=0; i<mStartedUsers.size(); i++) {
+                pw.print("u" + mStartedUsers.get(i) + " ");
+            }
+            pw.println();
             pw.println("Registered jobs:");
             if (mJobs.size() > 0) {
                 ArraySet<JobStatus> jobs = mJobs.getJobs();
@@ -1071,15 +1172,12 @@
                 mControllers.get(i).dumpControllerState(pw);
             }
             pw.println();
-            pw.println("Pending:");
-            for (int i=0; i<mPendingJobs.size(); i++) {
-                pw.println(mPendingJobs.get(i).hashCode());
-            }
+            pw.println(printPendingQueue());
             pw.println();
             pw.println("Active jobs:");
             for (int i=0; i<mActiveServices.size(); i++) {
                 JobServiceContext jsc = mActiveServices.get(i);
-                if (jsc.isAvailable()) {
+                if (jsc.getRunningJob() == null) {
                     continue;
                 } else {
                     final long timeout = jsc.getTimeoutElapsed();
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 5376043..dd634fa 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -59,7 +60,6 @@
  * To mitigate this, tearing down the context removes all messages from the handler, including any
  * tardy {@link #MSG_CANCEL}s. Additionally, we avoid sending duplicate onStopJob()
  * calls to the client after they've specified jobFinished().
- *
  */
 public class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {
     private static final boolean DEBUG = JobSchedulerService.DEBUG;
@@ -95,6 +95,8 @@
     /** Shutdown the job. Used when the client crashes and we can't die gracefully.*/
     private static final int MSG_SHUTDOWN_EXECUTION = 4;
 
+    public static final int NO_PREFERRED_UID = -1;
+
     private final Handler mCallbackHandler;
     /** Make callbacks to {@link JobSchedulerService} to inform on job completion status. */
     private final JobCompletedListener mCompletedListener;
@@ -117,7 +119,8 @@
      * Writes can only be done from the handler thread, or {@link #executeRunnableJob(JobStatus)}.
      */
     private JobStatus mRunningJob;
-    /** Binder to the client service. */
+    /** Used to store next job to run when current job is to be preempted. */
+    private int mPreferredUid;
     IJobService service;
 
     private final Object mLock = new Object();
@@ -138,17 +141,19 @@
 
     @VisibleForTesting
     JobServiceContext(Context context, IBatteryStats batteryStats,
-            JobCompletedListener completedListener, Looper looper) {
+                      JobCompletedListener completedListener, Looper looper) {
         mContext = context;
         mBatteryStats = batteryStats;
         mCallbackHandler = new JobServiceHandler(looper);
         mCompletedListener = completedListener;
         mAvailable = true;
+        mVerb = VERB_FINISHED;
+        mPreferredUid = NO_PREFERRED_UID;
     }
 
     /**
-     * Give a job to this context for execution. Callers must first check {@link #isAvailable()}
-     * to make sure this is a valid context.
+     * Give a job to this context for execution. Callers must first check {@link #getRunningJob()}
+     * and ensure it is null to make sure this is a valid context.
      * @param job The status of the job that we are going to run.
      * @return True if the job is valid and is running. False if the job cannot be executed.
      */
@@ -159,6 +164,8 @@
                 return false;
             }
 
+            mPreferredUid = NO_PREFERRED_UID;
+
             mRunningJob = job;
             final boolean isDeadlineExpired =
                     job.hasDeadlineConstraint() &&
@@ -184,7 +191,7 @@
                 return false;
             }
             try {
-                mBatteryStats.noteJobStart(job.getName(), job.getUid());
+                mBatteryStats.noteJobStart(job.getName(), job.getSourceUid());
             } catch (RemoteException e) {
                 // Whatever.
             }
@@ -206,17 +213,22 @@
     }
 
     /** Called externally when a job that was scheduled for execution should be cancelled. */
-    void cancelExecutingJob() {
-        mCallbackHandler.obtainMessage(MSG_CANCEL).sendToTarget();
+    void cancelExecutingJob(int reason) {
+        mCallbackHandler.obtainMessage(MSG_CANCEL, reason, 0 /* unused */).sendToTarget();
     }
 
-    /**
-     * @return Whether this context is available to handle incoming work.
-     */
-    boolean isAvailable() {
-        synchronized (mLock) {
-            return mAvailable;
-        }
+    void preemptExecutingJob() {
+        Message m = mCallbackHandler.obtainMessage(MSG_CANCEL);
+        m.arg1 = JobParameters.REASON_PREEMPT;
+        m.sendToTarget();
+    }
+
+    int getPreferredUid() {
+        return mPreferredUid;
+    }
+
+    void clearPreferredUid() {
+        mPreferredUid = NO_PREFERRED_UID;
     }
 
     long getExecutionStartTimeElapsed() {
@@ -277,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();
@@ -344,6 +356,11 @@
                     }
                     break;
                 case MSG_CANCEL:
+                    mParams.setStopReason(message.arg1);
+                    if (message.arg1 == JobParameters.REASON_PREEMPT) {
+                        mPreferredUid = mRunningJob != null ? mRunningJob.getUid() :
+                                NO_PREFERRED_UID;
+                    }
                     handleCancelH();
                     break;
                 case MSG_TIMEOUT:
@@ -481,6 +498,7 @@
 
         /** Process MSG_TIMEOUT here. */
         private void handleOpTimeoutH() {
+            mParams.setStopReason(JobParameters.REASON_TIMEOUT);
             switch (mVerb) {
                 case VERB_BINDING:
                     Slog.e(TAG, "Time-out while trying to bind " + mRunningJob.toShortString() +
@@ -549,7 +567,7 @@
                 }
                 completedJob = mRunningJob;
                 try {
-                    mBatteryStats.noteJobFinish(mRunningJob.getName(), mRunningJob.getUid());
+                    mBatteryStats.noteJobFinish(mRunningJob.getName(), mRunningJob.getSourceUid());
                 } catch (RemoteException e) {
                     // Whatever.
                 }
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index b8aa9dd..c88f5d7 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -312,7 +312,7 @@
                         Slog.d(TAG, "Saving job " + jobStatus.getJobId());
                     }
                     out.startTag(null, "job");
-                    addIdentifierAttributesToJobTag(out, jobStatus);
+                    addAttributesToJobTag(out, jobStatus);
                     writeConstraintsToXml(out, jobStatus);
                     writeExecutionCriteriaToXml(out, jobStatus);
                     writeBundleToXml(jobStatus.getExtras(), out);
@@ -337,13 +337,20 @@
             }
         }
 
-        /** Write out a tag with data comprising the required fields of this job and its client. */
-        private void addIdentifierAttributesToJobTag(XmlSerializer out, JobStatus jobStatus)
+        /** Write out a tag with data comprising the required fields and priority of this job and
+         * its client.
+         */
+        private void addAttributesToJobTag(XmlSerializer out, JobStatus jobStatus)
                 throws IOException {
             out.attribute(null, "jobid", Integer.toString(jobStatus.getJobId()));
             out.attribute(null, "package", jobStatus.getServiceComponent().getPackageName());
             out.attribute(null, "class", jobStatus.getServiceComponent().getClassName());
+            if (jobStatus.getSourcePackageName() != null) {
+                out.attribute(null, "sourcePackageName", jobStatus.getSourcePackageName());
+            }
+            out.attribute(null, "sourceUserId", String.valueOf(jobStatus.getSourceUserId()));
             out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
+            out.attribute(null, "priority", String.valueOf(jobStatus.getPriority()));
         }
 
         private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
@@ -361,9 +368,9 @@
             PersistableBundle copy = (PersistableBundle) bundle.clone();
             Set<String> keySet = bundle.keySet();
             for (String key: keySet) {
-                PersistableBundle b = copy.getPersistableBundle(key);
-                if (b != null) {
-                    PersistableBundle bCopy = deepCopyBundle(b, maxDepth-1);
+                Object o = copy.get(key);
+                if (o instanceof PersistableBundle) {
+                    PersistableBundle bCopy = deepCopyBundle((PersistableBundle) o, maxDepth-1);
                     copy.putPersistableBundle(key, bCopy);
                 }
             }
@@ -539,18 +546,27 @@
         private JobStatus restoreJobFromXml(XmlPullParser parser) throws XmlPullParserException,
                 IOException {
             JobInfo.Builder jobBuilder;
-            int uid;
+            int uid, userId;
 
-            // Read out job identifier attributes.
+            // Read out job identifier attributes and priority.
             try {
                 jobBuilder = buildBuilderFromXml(parser);
                 jobBuilder.setPersisted(true);
                 uid = Integer.valueOf(parser.getAttributeValue(null, "uid"));
+
+                String val = parser.getAttributeValue(null, "priority");
+                if (val != null) {
+                    jobBuilder.setPriority(Integer.valueOf(val));
+                }
+                val = parser.getAttributeValue(null, "sourceUserId");
+                userId = val == null ? -1 : Integer.valueOf(val);
             } catch (NumberFormatException e) {
                 Slog.e(TAG, "Error parsing job's required fields, skipping");
                 return null;
             }
 
+            final String sourcePackageName = parser.getAttributeValue(null, "sourcePackageName");
+
             int eventType;
             // Read out constraints tag.
             do {
@@ -664,8 +680,12 @@
             jobBuilder.setExtras(extras);
             parser.nextTag(); // Consume </extras>
 
-            return new JobStatus(
+            JobStatus js = new JobStatus(
                     jobBuilder.build(), uid, elapsedRuntimes.first, elapsedRuntimes.second);
+            if (userId != -1) {
+                js.setSource(sourcePackageName, userId);
+            }
+            return js;
         }
 
         private JobInfo.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 6fc02f6..c09e06c 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -65,9 +65,9 @@
     public void maybeStartTrackingJob(JobStatus jobStatus) {
         synchronized (mTrackedTasks) {
             mTrackedTasks.add(jobStatus);
-            String packageName = jobStatus.job.getService().getPackageName();
+            String packageName = jobStatus.getSourcePackageName();
             final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
-                    jobStatus.uId, jobStatus.getUserId());
+                    jobStatus.getSourceUid(), jobStatus.getSourceUserId());
             if (DEBUG) {
                 Slog.d(LOG_TAG, "Start tracking, setting idle state of "
                         + packageName + " to " + appIdle);
@@ -89,7 +89,7 @@
         pw.println("Parole On: " + mAppIdleParoleOn);
         synchronized (mTrackedTasks) {
             for (JobStatus task : mTrackedTasks) {
-                pw.print(task.job.getService().getPackageName());
+                pw.print(task.getSourcePackageName());
                 pw.print(":idle=" + !task.appNotIdleConstraintSatisfied.get());
                 pw.print(", ");
             }
@@ -106,9 +106,9 @@
             }
             mAppIdleParoleOn = isAppIdleParoleOn;
             for (JobStatus task : mTrackedTasks) {
-                String packageName = task.job.getService().getPackageName();
+                String packageName = task.getSourcePackageName();
                 final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
-                        task.uId, task.getUserId());
+                        task.getSourceUid(), task.getSourceUserId());
                 if (DEBUG) {
                     Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle);
                 }
@@ -133,8 +133,8 @@
                     return;
                 }
                 for (JobStatus task : mTrackedTasks) {
-                    if (task.job.getService().getPackageName().equals(packageName)
-                            && task.getUserId() == userId) {
+                    if (task.getSourcePackageName().equals(packageName)
+                            && task.getSourceUserId() == userId) {
                         if (task.appNotIdleConstraintSatisfied.get() != !idle) {
                             if (DEBUG) {
                                 Slog.d(LOG_TAG, "App Idle state changed, setting idle state of "
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 92df851..fe5e8c9 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -34,14 +34,13 @@
 public class IdleController extends StateController {
     private static final String TAG = "IdleController";
 
-    // Policy: we decide that we're "idle" if the device has been unused /
-    // screen off or dreaming for at least this long
-    private static final long INACTIVITY_IDLE_THRESHOLD = 71 * 60 * 1000; // millis; 71 min
-    private static final long IDLE_WINDOW_SLOP = 5 * 60 * 1000; // 5 minute window, to be nice
-
     private static final String ACTION_TRIGGER_IDLE =
             "com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE";
 
+    // Policy: we decide that we're "idle" if the device has been unused /
+    // screen off or dreaming for at least this long
+    private long mInactivityIdleThreshold;
+    private long mIdleWindowSlop;
     final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
     IdlenessTracker mIdleTracker;
 
@@ -100,6 +99,10 @@
      * significant state changes occur
      */
     private void initIdleStateTracking() {
+        mInactivityIdleThreshold = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_jobSchedulerInactivityIdleThreshold);
+        mIdleWindowSlop = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_jobSchedulerIdleWindowSlop);
         mIdleTracker = new IdlenessTracker();
         mIdleTracker.startTracking();
     }
@@ -168,14 +171,14 @@
                 // alarm that will tell us when we have decided the device is
                 // truly idle.
                 final long nowElapsed = SystemClock.elapsedRealtime();
-                final long when = nowElapsed + INACTIVITY_IDLE_THRESHOLD;
+                final long when = nowElapsed + mInactivityIdleThreshold;
                 if (DEBUG) {
                     Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
                             + when);
                 }
                 mScreenOn = false;
                 mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                        when, IDLE_WINDOW_SLOP, mIdleTriggerIntent);
+                        when, mIdleWindowSlop, mIdleTriggerIntent);
             } else if (action.equals(ACTION_TRIGGER_IDLE)) {
                 // idle time starts now. Do not set mIdle if screen is on.
                 if (!mIdle && !mScreenOn) {
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 060a93e..e6e9e49 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -16,9 +16,11 @@
 
 package com.android.server.job.controllers;
 
+import android.app.AppGlobals;
 import android.app.job.JobInfo;
 import android.content.ComponentName;
 import android.os.PersistableBundle;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.text.format.DateUtils;
@@ -47,6 +49,10 @@
     final String name;
     final String tag;
 
+    String sourcePackageName;
+    int sourceUserId = -1;
+    int sourceUid = -1;
+
     // Constraints.
     final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean();
     final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean();
@@ -77,6 +83,7 @@
     private JobStatus(JobInfo job, int uId, int numFailures) {
         this.job = job;
         this.uId = uId;
+        this.sourceUid = uId;
         this.name = job.getService().flattenToShortString();
         this.tag = "*job*/" + this.name;
         this.numFailures = numFailures;
@@ -85,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();
     }
@@ -125,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;
@@ -146,6 +157,21 @@
         return job.getService();
     }
 
+    public String getSourcePackageName() {
+        return sourcePackageName != null ? sourcePackageName : job.getService().getPackageName();
+    }
+
+    public int getSourceUid() {
+        return sourceUid;
+    }
+
+    public int getSourceUserId() {
+        if (sourceUserId == -1) {
+            sourceUserId = getUserId();
+        }
+        return sourceUserId;
+    }
+
     public int getUserId() {
         return UserHandle.getUserId(uId);
     }
@@ -166,6 +192,10 @@
         return job.getExtras();
     }
 
+    public int getPriority() {
+        return job.getPriority();
+    }
+
     public boolean hasConnectivityConstraint() {
         return job.getNetworkType() == JobInfo.NETWORK_TYPE_ANY;
     }
@@ -259,6 +289,22 @@
         }
     }
 
+    public void setSource(String sourcePackageName, int sourceUserId) {
+        this.sourcePackageName = sourcePackageName;
+        this.sourceUserId = sourceUserId;
+        try {
+            sourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0,
+                    sourceUserId);
+        } catch (RemoteException ex) {
+            // Can't happen, PackageManager runs in the same process.
+        }
+        if (sourceUid == -1) {
+            sourceUid = uId;
+            this.sourceUserId = getUserId();
+            this.sourcePackageName = null;
+        }
+    }
+
     /**
      * Convenience function to identify a job uniquely without pulling all the data that
      * {@link #toString()} returns.
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/lights/Light.java b/services/core/java/com/android/server/lights/Light.java
index b496b4c6..b18a181 100644
--- a/services/core/java/com/android/server/lights/Light.java
+++ b/services/core/java/com/android/server/lights/Light.java
@@ -31,6 +31,11 @@
      */
     public static final int BRIGHTNESS_MODE_SENSOR = 1;
 
+    /**
+     * Low-persistence light mode.
+     */
+    public static final int BRIGHTNESS_MODE_LOW_PERSISTENCE = 2;
+
     public abstract void setBrightness(int brightness);
     public abstract void setBrightness(int brightness, int brightnessMode);
     public abstract void setColor(int color);
@@ -38,4 +43,4 @@
     public abstract void pulse();
     public abstract void pulse(int color, int onMS);
     public abstract void turnOff();
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index ed884ef..257c7da 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -17,6 +17,8 @@
 package com.android.server.lights;
 
 import com.android.server.SystemService;
+import com.android.server.vr.VrManagerInternal;
+import com.android.server.vr.VrStateListener;
 
 import android.content.Context;
 import android.os.Handler;
@@ -72,6 +74,9 @@
         @Override
         public void pulse(int color, int onMS) {
             synchronized (this) {
+                if (mBrightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
+                    return;
+                }
                 if (mColor == 0 && !mFlashing) {
                     setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER);
                     mColor = 0;
@@ -87,6 +92,20 @@
             }
         }
 
+        void enableLowPersistence() {
+            synchronized(this) {
+                setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_LOW_PERSISTENCE);
+                mLocked = true;
+            }
+        }
+
+        void disableLowPersistence() {
+            synchronized(this) {
+                mLocked = false;
+                setLightLocked(mLastColor, LIGHT_FLASH_NONE, 0, 0, mLastBrightnessMode);
+            }
+        }
+
         private void stopFlashing() {
             synchronized (this) {
                 setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER);
@@ -94,13 +113,17 @@
         }
 
         private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
-            if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {
+            if (!mLocked && (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS ||
+                    mBrightnessMode != brightnessMode)) {
                 if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
-                        + Integer.toHexString(color));
+                        + Integer.toHexString(color) + ": brightnessMode=" + brightnessMode);
+                mLastColor = mColor;
                 mColor = color;
                 mMode = mode;
                 mOnMS = onMS;
                 mOffMS = offMS;
+                mLastBrightnessMode = mBrightnessMode;
+                mBrightnessMode = brightnessMode;
                 Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
                         + Integer.toHexString(color) + ")");
                 try {
@@ -117,6 +140,10 @@
         private int mOnMS;
         private int mOffMS;
         private boolean mFlashing;
+        private int mBrightnessMode;
+        private int mLastBrightnessMode;
+        private int mLastColor;
+        private boolean mLocked;
     }
 
     public LightsService(Context context) {
@@ -134,6 +161,28 @@
         publishLocalService(LightsManager.class, mService);
     }
 
+    @Override
+    public void onBootPhase(int phase) {
+        if (phase == PHASE_SYSTEM_SERVICES_READY) {
+            getLocalService(VrManagerInternal.class).registerListener(mVrStateListener);
+        }
+    }
+
+    private final VrStateListener mVrStateListener = new VrStateListener() {
+        @Override
+        public void onVrStateChanged(boolean enabled) {
+            LightImpl l = mLights[LightsManager.LIGHT_ID_BACKLIGHT];
+            if (enabled) {
+                if (DEBUG) Slog.v(TAG, "VR mode enabled, setting brightness to low persistence");
+                l.enableLowPersistence();
+
+            } else {
+                if (DEBUG) Slog.v(TAG, "VR mode disabled, resetting brightnes");
+                l.disableLowPersistence();
+            }
+        }
+    };
+
     private final LightsManager mService = new LightsManager() {
         @Override
         public Light getLight(int id) {
diff --git a/services/core/java/com/android/server/media/MediaResourceMonitorService.java b/services/core/java/com/android/server/media/MediaResourceMonitorService.java
new file mode 100644
index 0000000..50dd607
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaResourceMonitorService.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.content.Intent;
+import android.media.IMediaResourceMonitor;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+import com.android.server.SystemService;
+
+import java.util.List;
+
+/** This class provides a system service that monitors media resource usage. */
+public class MediaResourceMonitorService extends SystemService {
+    private static final String TAG = "MediaResourceMonitor";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final String SERVICE_NAME = "media_resource_monitor";
+
+    /*
+     *  Resource types. Should be in sync with:
+     *  frameworks/av/media/libmedia/MediaResource.cpp
+     */
+    private static final String RESOURCE_AUDIO_CODEC = "audio-codec";
+    private static final String RESOURCE_VIDEO_CODEC = "video-codec";
+
+    private final MediaResourceMonitorImpl mMediaResourceMonitorImpl;
+
+    public MediaResourceMonitorService(Context context) {
+        super(context);
+        mMediaResourceMonitorImpl = new MediaResourceMonitorImpl();
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(SERVICE_NAME, mMediaResourceMonitorImpl);
+    }
+
+    class MediaResourceMonitorImpl extends IMediaResourceMonitor.Stub {
+        @Override
+        public void notifyResourceGranted(int pid, String type, String subType, long value)
+                throws RemoteException {
+            if (DEBUG) {
+                Slog.d(TAG, "notifyResourceGranted(pid=" + pid + ", type=" + type + ", subType="
+                        + subType + ", value=" + value + ")");
+            }
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                String pkgNames[] = getPackageNamesFromPid(pid);
+                Integer resourceType = null;
+                if (RESOURCE_AUDIO_CODEC.equals(subType)) {
+                    resourceType = Intent.EXTRA_MEDIA_RESOURCE_TYPE_AUDIO_CODEC;
+                } else if (RESOURCE_VIDEO_CODEC.equals(subType)) {
+                    resourceType = Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC;
+                }
+                if (pkgNames != null && resourceType != null) {
+                    Intent intent = new Intent(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
+                    intent.putExtra(Intent.EXTRA_PACKAGES, pkgNames);
+                    intent.putExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE, resourceType);
+                    getContext().sendBroadcastAsUser(intent,
+                            new UserHandle(ActivityManager.getCurrentUser()),
+                            android.Manifest.permission.RECEIVE_MEDIA_RESOURCE_USAGE);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        private String[] getPackageNamesFromPid(int pid) {
+            try {
+                for (ActivityManager.RunningAppProcessInfo proc :
+                        ActivityManagerNative.getDefault().getRunningAppProcesses()) {
+                    if (proc.pid == pid) {
+                        return proc.pkgList;
+                    }
+                }
+            } catch (RemoteException e) {
+                Slog.w(TAG, "ActivityManager.getRunningAppProcesses() failed");
+            }
+            return 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/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 018bf2d..b1fe68c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1727,6 +1727,14 @@
         }
 
         @Override
+        public int getRuleInstanceCount(ComponentName owner) throws RemoteException {
+            Preconditions.checkNotNull(owner, "Owner is null");
+            enforceSystemOrSystemUI("getRuleInstanceCount");
+
+            return mZenModeHelper.getCurrentInstanceCount(owner);
+        }
+
+        @Override
         public void setInterruptionFilter(String pkg, int filter) throws RemoteException {
             enforcePolicyAccess(pkg, "setInterruptionFilter");
             final int zen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f7043a6..1d91fb7 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -27,7 +27,10 @@
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.database.ContentObserver;
@@ -45,7 +48,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
-import android.service.notification.IConditionListener;
+import android.service.notification.ConditionProviderService;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.EventInfo;
 import android.service.notification.ZenModeConfig.ScheduleInfo;
@@ -91,6 +94,7 @@
     private final ZenModeConditions mConditions;
     private final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
     private final Metrics mMetrics = new Metrics();
+    private final ConditionProviders.Config mServiceConfig;
 
     private int mZenMode;
     private int mUser = UserHandle.USER_SYSTEM;
@@ -113,6 +117,7 @@
         mSettingsObserver.observe();
         mFiltering = new ZenModeFiltering(mContext);
         mConditions = new ZenModeConditions(this, conditionProviders);
+        mServiceConfig = conditionProviders.getConfig();
     }
 
     public Looper getLooper() {
@@ -197,7 +202,7 @@
             config.user = user;
         }
         synchronized (mConfig) {
-            setConfig(config, "onUserSwitched");
+            setConfigLocked(config, "onUserSwitched");
         }
         cleanUpZenRules();
     }
@@ -257,22 +262,34 @@
     }
 
     public AutomaticZenRule addAutomaticZenRule(AutomaticZenRule automaticZenRule, String reason) {
+        if (!TextUtils.isEmpty(automaticZenRule.getId())) {
+            throw new IllegalArgumentException("Rule already exists");
+        }
+        if (!isSystemRule(automaticZenRule)) {
+            ServiceInfo owner = getServiceInfo(automaticZenRule.getOwner());
+            if (owner == null) {
+                throw new IllegalArgumentException("Owner is not a condition provider service");
+            }
+
+            final int ruleInstanceLimit = owner.metaData.getInt(
+                    ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
+            if (ruleInstanceLimit > 0 && ruleInstanceLimit
+                    < (getCurrentInstanceCount(automaticZenRule.getOwner()) + 1)) {
+                throw new IllegalArgumentException("Rule instance limit exceeded");
+            }
+        }
+
         ZenModeConfig newConfig;
         synchronized (mConfig) {
             if (mConfig == null) return null;
             if (DEBUG) {
-                Log.d(TAG,
-                        "addAutomaticZenRule zenRule= " + automaticZenRule + " reason=" + reason);
-            }
-            if (!TextUtils.isEmpty(automaticZenRule.getId())) {
-                throw new IllegalArgumentException("Rule already exists");
+                Log.d(TAG, "addAutomaticZenRule rule= " + automaticZenRule + " reason=" + reason);
             }
             newConfig = mConfig.copy();
-
             ZenRule rule = new ZenRule();
             populateZenRule(automaticZenRule, rule, true);
             newConfig.automaticRules.put(rule.id, rule);
-            if (setConfig(newConfig, reason, true)) {
+            if (setConfigLocked(newConfig, reason, true)) {
                 return createAutomaticZenRule(rule);
             } else {
                 return null;
@@ -302,7 +319,7 @@
             }
             populateZenRule(automaticZenRule, rule, false);
             newConfig.automaticRules.put(ruleId, rule);
-            return setConfig(newConfig, reason, true);
+            return setConfigLocked(newConfig, reason, true);
         }
     }
 
@@ -320,7 +337,7 @@
                 throw new SecurityException(
                         "Cannot delete rules not owned by your condition provider");
             }
-            return setConfig(newConfig, reason, true);
+            return setConfigLocked(newConfig, reason, true);
         }
     }
 
@@ -336,10 +353,22 @@
                     newConfig.automaticRules.removeAt(i);
                 }
             }
-            return setConfig(newConfig, reason, true);
+            return setConfigLocked(newConfig, reason, true);
         }
     }
 
+    public int getCurrentInstanceCount(ComponentName owner) {
+        int count = 0;
+        synchronized (mConfig) {
+            for (ZenRule rule : mConfig.automaticRules.values()) {
+                if (rule.component != null && rule.component.equals(owner)) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
     public boolean canManageAutomaticZenRule(ZenRule rule) {
         final int callingUid = Binder.getCallingUid();
         if (callingUid == 0 || callingUid == Process.SYSTEM_UID) {
@@ -361,6 +390,29 @@
         }
     }
 
+    private boolean isSystemRule(AutomaticZenRule rule) {
+        return ZenModeConfig.SYSTEM_AUTHORITY.equals(rule.getOwner().getPackageName());
+    }
+
+    private ServiceInfo getServiceInfo(ComponentName owner) {
+        Intent queryIntent = new Intent();
+        queryIntent.setComponent(owner);
+        List<ResolveInfo> installedServices = mPm.queryIntentServicesAsUser(
+                queryIntent,
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
+                UserHandle.getCallingUserId());
+        if (installedServices != null) {
+            for (int i = 0, count = installedServices.size(); i < count; i++) {
+                ResolveInfo resolveInfo = installedServices.get(i);
+                ServiceInfo info = resolveInfo.serviceInfo;
+                if (mServiceConfig.bindPermission.equals(info.permission)) {
+                    return info;
+                }
+            }
+        }
+        return null;
+    }
+
     private void populateZenRule(AutomaticZenRule automaticZenRule, ZenRule rule, boolean isNew) {
         if (isNew) {
             rule.id = ZenModeConfig.newRuleId();
@@ -413,7 +465,7 @@
                 newRule.conditionId = conditionId;
                 newConfig.manualRule = newRule;
             }
-            setConfig(newConfig, reason, setRingerMode);
+            setConfigLocked(newConfig, reason, setRingerMode);
         }
     }
 
@@ -478,7 +530,7 @@
             }
             if (DEBUG) Log.d(TAG, "readXml");
             synchronized (mConfig) {
-                setConfig(config, "readXml");
+                setConfigLocked(config, "readXml");
             }
         }
     }
@@ -507,7 +559,7 @@
         synchronized (mConfig) {
             final ZenModeConfig newConfig = mConfig.copy();
             newConfig.applyNotificationPolicy(policy);
-            setConfig(newConfig, "setNotificationPolicy");
+            setConfigLocked(newConfig, "setNotificationPolicy");
         }
     }
 
@@ -530,7 +582,7 @@
                     }
                 }
             }
-            setConfig(newConfig, "cleanUpZenRules");
+            setConfigLocked(newConfig, "cleanUpZenRules");
         }
     }
 
@@ -543,30 +595,30 @@
         }
     }
 
-    public boolean setConfig(ZenModeConfig config, String reason) {
-        return setConfig(config, reason, true /*setRingerMode*/);
+    public boolean setConfigLocked(ZenModeConfig config, String reason) {
+        return setConfigLocked(config, reason, true /*setRingerMode*/);
     }
 
     public void setConfigAsync(ZenModeConfig config, String reason) {
         mHandler.postSetConfig(config, reason);
     }
 
-    private boolean setConfig(ZenModeConfig config, String reason, boolean setRingerMode) {
+    private boolean setConfigLocked(ZenModeConfig config, String reason, boolean setRingerMode) {
         final long identity = Binder.clearCallingIdentity();
         try {
             if (config == null || !config.isValid()) {
-                Log.w(TAG, "Invalid config in setConfig; " + config);
+                Log.w(TAG, "Invalid config in setConfigLocked; " + config);
                 return false;
             }
             if (config.user != mUser) {
                 // simply store away for background users
                 mConfigs.put(config.user, config);
-                if (DEBUG) Log.d(TAG, "setConfig: store config for user " + config.user);
+                if (DEBUG) Log.d(TAG, "setConfigLocked: store config for user " + config.user);
                 return true;
             }
             mConditions.evaluateConfig(config, false /*processSubscriptions*/);  // may modify config
             mConfigs.put(config.user, config);
-            if (DEBUG) Log.d(TAG, "setConfig reason=" + reason, new Throwable());
+            if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable());
             ZenLog.traceConfig(reason, mConfig, config);
             final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
                     getNotificationPolicy(config));
@@ -1041,7 +1093,7 @@
                 case MSG_SET_CONFIG:
                     ConfigMessageData configData = (ConfigMessageData)msg.obj;
                     synchronized (mConfig) {
-                        setConfig(configData.config, configData.reason);
+                        setConfigLocked(configData.config, configData.reason);
                     }
                     break;
             }
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index af20679..89e89b0 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -24,6 +24,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.util.ArraySet;
 import android.util.Log;
 
@@ -50,12 +51,13 @@
 
     final AtomicBoolean mIdleTime = new AtomicBoolean(false);
 
-    public static void schedule(Context context, long minLatency) {
+    private boolean useJitProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
+
+    public static void schedule(Context context) {
         JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
         JobInfo job = new JobInfo.Builder(BACKGROUND_DEXOPT_JOB, sDexoptServiceName)
                 .setRequiresDeviceIdle(true)
                 .setRequiresCharging(true)
-                .setMinimumLatency(minLatency)
                 .setPeriodic(TimeUnit.DAYS.toMillis(1))
                 .build();
         js.schedule(job);
@@ -63,16 +65,17 @@
 
     @Override
     public boolean onStartJob(JobParameters params) {
-        Log.i(TAG, "onIdleStart");
+        Log.i(TAG, "onStartJob");
         final PackageManagerService pm =
                 (PackageManagerService)ServiceManager.getService("package");
 
         if (pm.isStorageLow()) {
-            schedule(BackgroundDexOptService.this, RETRY_LATENCY);
+            Log.i(TAG, "Low storage, skipping this run");
             return false;
         }
-        final ArraySet<String> pkgs = pm.getPackagesThatNeedDexOpt();
-        if (pkgs == null) {
+        final ArraySet<String> pkgs = pm.getOptimizablePackages();
+        if (pkgs == null || pkgs.isEmpty()) {
+            Log.i(TAG, "No packages to optimize");
             return false;
         }
 
@@ -83,15 +86,15 @@
             public void run() {
                 for (String pkg : pkgs) {
                     if (!mIdleTime.get()) {
-                        // stopped while still working, so we need to reschedule
-                        schedule(BackgroundDexOptService.this, 0);
+                        // Out of the idle state. Stop the compilation.
                         return;
                     }
                     if (sFailedPackageNames.contains(pkg)) {
                         // skip previously failing package
                         continue;
                     }
-                    if (!pm.performDexOpt(pkg, null /* instruction set */)) {
+                    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 190eca6..cf876ee 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.PackageStats;
@@ -28,6 +29,9 @@
 
 import dalvik.system.VMRuntime;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 public final class Installer extends SystemService {
     private static final String TAG = "Installer";
 
@@ -43,11 +47,20 @@
     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 = {
+            FLAG_DE_STORAGE,
+            FLAG_CE_STORAGE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StorageFlags {}
 
     public static final int FLAG_DE_STORAGE = 1 << 0;
     public static final int FLAG_CE_STORAGE = 1 << 1;
+
     public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 2;
     public static final int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 3;
 
@@ -73,8 +86,9 @@
     }
 
     public void createAppData(String uuid, String pkgname, int userid, int flags, int appid,
-            String seinfo) throws InstallerException {
-        mInstaller.execute("create_app_data", uuid, pkgname, userid, flags, appid, seinfo);
+            String seinfo, int targetSdkVersion) throws InstallerException {
+        mInstaller.execute("create_app_data", uuid, pkgname, userid, flags, appid, seinfo,
+            targetSdkVersion);
     }
 
     public void restoreconAppData(String uuid, String pkgname, int userid, int flags, int appid,
@@ -94,9 +108,10 @@
     }
 
     public void moveCompleteApp(String from_uuid, String to_uuid, String package_name,
-            String data_app_name, int appid, String seinfo) throws InstallerException {
+            String data_app_name, int appid, String seinfo, int targetSdkVersion)
+            throws InstallerException {
         mInstaller.execute("move_complete_app", from_uuid, to_uuid, package_name,
-                data_app_name, appid, seinfo);
+                data_app_name, appid, seinfo, targetSdkVersion);
     }
 
     public void getAppSize(String uuid, String pkgname, int userid, int flags, String apkPath,
@@ -128,17 +143,19 @@
     }
 
     public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
-            int dexFlags) throws InstallerException {
+            int dexFlags, String volumeUuid, boolean useProfiles) throws InstallerException {
         assertValidInstructionSet(instructionSet);
-        mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags);
+        mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags,
+                volumeUuid, useProfiles);
     }
 
     public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
-            int dexoptNeeded, @Nullable String outputPath, int dexFlags)
+            int dexoptNeeded, @Nullable String outputPath, int dexFlags,
+            String volumeUuid, boolean useProfiles)
                     throws InstallerException {
         assertValidInstructionSet(instructionSet);
         mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded,
-                outputPath, dexFlags);
+                outputPath, dexFlags, volumeUuid, useProfiles);
     }
 
     public void idmap(String targetApkPath, String overlayApkPath, int uid)
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 b45a922..482217c 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -23,6 +23,7 @@
 import android.os.PowerManager;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.os.storage.StorageManager;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
@@ -40,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;
 
@@ -68,6 +69,11 @@
         mDexoptWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*dexopt*");
     }
 
+    static boolean canOptimizePackage(PackageParser.Package pkg) {
+        return pkg.canHaveOatDir() &&
+                ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0);
+    }
+
     /**
      * Performs dexopt on all code paths and libraries of the specified package for specified
      * instruction sets.
@@ -76,7 +82,7 @@
      * {@link PackageManagerService#mInstallLock}.
      */
     int performDexOpt(PackageParser.Package pkg, String[] instructionSets,
-            boolean inclDependencies) {
+            boolean inclDependencies, String volumeUuid, boolean useProfiles, boolean extractOnly) {
         ArraySet<String> done;
         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
             done = new ArraySet<String>();
@@ -91,7 +97,8 @@
                 mDexoptWakeLock.acquire();
             }
             try {
-                return performDexOptLI(pkg, instructionSets, done);
+                return performDexOptLI(pkg, instructionSets, done, volumeUuid, useProfiles,
+                        extractOnly);
             } finally {
                 if (useLock) {
                     mDexoptWakeLock.release();
@@ -101,7 +108,7 @@
     }
 
     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
-            ArraySet<String> done) {
+            ArraySet<String> done, String volumeUuid, boolean useProfiles, boolean extractOnly) {
         final String[] instructionSets = targetInstructionSets != null ?
                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
 
@@ -115,7 +122,7 @@
             }
         }
 
-        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
+        if (!canOptimizePackage(pkg)) {
             return DEX_OPT_SKIPPED;
         }
 
@@ -124,18 +131,15 @@
 
         final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
         boolean performedDexOpt = false;
-        // There are three basic cases here:
-        // 1.) we need to dexopt, either because we are forced or it is needed
-        // 2.) we are deferring a needed dexopt
-        // 3.) we are skipping an unneeded dexopt
         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
-            if (pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
+            if (!useProfiles && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
+                // Skip only if we do not use profiles since they might trigger a recompilation.
                 continue;
             }
 
             for (String path : paths) {
-                final int dexoptNeeded;
+                int dexoptNeeded;
                 try {
                     dexoptNeeded = DexFile.getDexOptNeeded(path, pkg.packageName,
                             dexCodeInstructionSet, /* defer */false);
@@ -144,47 +148,58 @@
                     return DEX_OPT_FAILED;
                 }
 
-                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
-                    final String dexoptType;
-                    String oatDir = null;
-                    if (dexoptNeeded == DexFile.DEX2OAT_NEEDED) {
-                        dexoptType = "dex2oat";
-                        oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
-                    } else if (dexoptNeeded == DexFile.PATCHOAT_NEEDED) {
-                        dexoptType = "patchoat";
-                    } else if (dexoptNeeded == DexFile.SELF_PATCHOAT_NEEDED) {
-                        dexoptType = "self patchoat";
+                if (dexoptNeeded == DexFile.NO_DEXOPT_NEEDED) {
+                    if (useProfiles) {
+                        // If we do a profile guided compilation then we might recompile the same
+                        // package if more profile information is available.
+                        dexoptNeeded = DexFile.DEX2OAT_NEEDED;
                     } else {
-                        throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
+                        // No dexopt needed and we don't use profiles. Nothing to do.
+                        continue;
                     }
+                }
+                final String dexoptType;
+                String oatDir = null;
+                if (dexoptNeeded == DexFile.DEX2OAT_NEEDED) {
+                    dexoptType = "dex2oat";
+                    oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
+                } else if (dexoptNeeded == DexFile.PATCHOAT_NEEDED) {
+                    dexoptType = "patchoat";
+                } else if (dexoptNeeded == DexFile.SELF_PATCHOAT_NEEDED) {
+                    dexoptType = "self patchoat";
+                } else {
+                    throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
+                }
 
-                    Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
-                            + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
-                            + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
-                            + " 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)
-                            | DEXOPT_BOOTCOMPLETE;
-                    try {
-                        mPackageManagerService.mInstaller.dexopt(path, sharedGid,
-                                pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir,
-                                dexFlags);
-                        performedDexOpt = true;
-                    } catch (InstallerException e) {
-                        Slog.w(TAG, "Failed to dexopt", e);
-                    }
+                Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
+                        + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
+                        + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
+                        + " extractOnly=" + extractOnly + " oatDir = " + oatDir);
+                final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+                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);
+                    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
@@ -235,7 +250,11 @@
             PackageParser.Package libPkg = mPackageManagerService.findSharedNonSystemLibrary(
                     libName);
             if (libPkg != null && !done.contains(libName)) {
-                performDexOptLI(libPkg, instructionSets, done);
+                // 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,
+                        /* extractOnly */ false);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerException.java b/services/core/java/com/android/server/pm/PackageManagerException.java
index d04eedc..f243e63 100644
--- a/services/core/java/com/android/server/pm/PackageManagerException.java
+++ b/services/core/java/com/android/server/pm/PackageManagerException.java
@@ -25,6 +25,11 @@
 public class PackageManagerException extends Exception {
     public final int error;
 
+    public PackageManagerException(String detailMessage) {
+        super(detailMessage);
+        this.error = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+    }
+
     public PackageManagerException(int error, String detailMessage) {
         super(detailMessage);
         this.error = error;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f777faf..9d17f8f 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;
@@ -46,7 +47,6 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
-import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
@@ -76,7 +76,6 @@
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 import static android.system.OsConstants.O_CREAT;
 import static android.system.OsConstants.O_RDWR;
-
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
@@ -192,7 +191,6 @@
 import android.security.SystemKeyStore;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.system.StructStat;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
@@ -227,6 +225,7 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.XmlUtils;
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
 import com.android.server.IntentResolver;
@@ -234,6 +233,7 @@
 import com.android.server.ServiceThread;
 import com.android.server.SystemConfig;
 import com.android.server.Watchdog;
+import com.android.server.pm.Installer.StorageFlags;
 import com.android.server.pm.PermissionsState.PermissionState;
 import com.android.server.pm.Settings.DatabaseVersion;
 import com.android.server.pm.Settings.VersionInfo;
@@ -316,6 +316,7 @@
     private static final boolean DEBUG_ABI_SELECTION = false;
     private static final boolean DEBUG_EPHEMERAL = false;
     private static final boolean DEBUG_TRIAGED_MISSING = false;
+    private static final boolean DEBUG_APP_DATA = false;
 
     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
 
@@ -518,9 +519,6 @@
     // If mac_permissions.xml was found for seinfo labeling.
     boolean mFoundPolicyFile;
 
-    // If a recursive restorecon of /data/data/<pkg> is needed.
-    private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
-
     private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
 
     public static final class SharedLibraryEntry {
@@ -630,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;
@@ -978,6 +979,30 @@
     private static final String TAG_DEFAULT_APPS = "da";
     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
 
+    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
+    private static final String TAG_ALL_GRANTS = "rt-grants";
+    private static final String TAG_GRANT = "grant";
+    private static final String ATTR_PACKAGE_NAME = "pkg";
+
+    private static final String TAG_PERMISSION = "perm";
+    private static final String ATTR_PERMISSION_NAME = "name";
+    private static final String ATTR_IS_GRANTED = "g";
+    private static final String ATTR_USER_SET = "set";
+    private static final String ATTR_USER_FIXED = "fixed";
+    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
+
+    // System/policy permission grants are not backed up
+    private static final int SYSTEM_RUNTIME_GRANT_MASK =
+            FLAG_PERMISSION_POLICY_FIXED
+            | FLAG_PERMISSION_SYSTEM_FIXED
+            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
+
+    // And we back up these user-adjusted states
+    private static final int USER_RUNTIME_GRANT_MASK =
+            FLAG_PERMISSION_USER_SET
+            | FLAG_PERMISSION_USER_FIXED
+            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+
     final @Nullable String mRequiredVerifierPackage;
     final @Nullable String mRequiredInstallerPackage;
 
@@ -1490,16 +1515,25 @@
                                 deleteOld = true;
                             }
 
-                            // If this app is a browser and it's newly-installed for some
-                            // users, clear any default-browser state in those users
+
+                            // Work that needs to happen on first install within each user
                             if (firstUsers.length > 0) {
-                                // the app's nature doesn't depend on the user, so we can just
-                                // check its browser nature in any user and generalize.
-                                if (packageIsBrowser(packageName, firstUsers[0])) {
+                                for (int userId : firstUsers) {
                                     synchronized (mPackages) {
-                                        for (int userId : firstUsers) {
-                                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
+                                        // If this app is a browser and it's newly-installed for
+                                        // some users, clear any default-browser state in those
+                                        // users.  The app's nature doesn't depend on the user,
+                                        // so we can just check its browser nature in any user
+                                        // and generalize.
+                                        if (packageIsBrowser(packageName, firstUsers[0])) {
+                                            mSettings.setDefaultBrowserPackageNameLPw(
+                                                    null, userId);
                                         }
+
+                                        // We may also need to apply pending (restored) runtime
+                                        // permission grants within these users.
+                                        mSettings.applyPendingPermissionGrantsLPw(
+                                                packageName, userId);
                                     }
                                 }
                             }
@@ -1750,7 +1784,7 @@
         @Override
         public void onVolumeForgotten(String fsUuid) {
             if (TextUtils.isEmpty(fsUuid)) {
-                Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring");
+                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
                 return;
             }
 
@@ -2063,8 +2097,12 @@
                         try {
                             int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
+                                // Shared libraries do not have profiles so we perform a full
+                                // AOT compilation.
                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
-                                        dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/);
+                                        dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
+                                        StorageManager.UUID_PRIVATE_INTERNAL,
+                                        false /*useProfiles*/);
                             }
                         } catch (FileNotFoundException e) {
                             Slog.w(TAG, "Library not found: " + lib);
@@ -2342,6 +2380,17 @@
                 }
             }
 
+            // Prepare storage for system user really early during boot,
+            // since core system apps like SettingsProvider and SystemUI
+            // can't wait for user to start
+            final int flags;
+            if (StorageManager.isFileBasedEncryptionEnabled()) {
+                flags = Installer.FLAG_DE_STORAGE;
+            } else {
+                flags = Installer.FLAG_DE_STORAGE | Installer.FLAG_CE_STORAGE;
+            }
+            reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, flags);
+
             // If this is first boot after an OTA, and a normal boot, then
             // we need to clear code cache directories.
             if (mIsUpgrade && !onlyCore) {
@@ -3213,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);
     }
 
@@ -6579,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 {
@@ -6606,25 +6672,30 @@
         }
     }
 
+    // TODO: this is not used nor needed. Delete it.
     @Override
     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
-        return performDexOptTraced(packageName, instructionSet);
+        return performDexOptTraced(packageName, instructionSet, false /* useProfiles */,
+                false /* extractOnly */);
     }
 
-    public boolean performDexOpt(String packageName, String instructionSet) {
-        return performDexOptTraced(packageName, instructionSet);
+    public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
+            boolean extractOnly) {
+        return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly);
     }
 
-    private boolean performDexOptTraced(String packageName, String instructionSet) {
+    private boolean performDexOptTraced(String packageName, String instructionSet,
+                boolean useProfiles, boolean extractOnly) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
         try {
-            return performDexOptInternal(packageName, instructionSet);
+            return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly);
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
     }
 
-    private boolean performDexOptInternal(String packageName, String instructionSet) {
+    private boolean performDexOptInternal(String packageName, String instructionSet,
+                boolean useProfiles, boolean extractOnly) {
         PackageParser.Package p;
         final String targetInstructionSet;
         synchronized (mPackages) {
@@ -6636,7 +6707,8 @@
 
             targetInstructionSet = instructionSet != null ? instructionSet :
                     getPrimaryInstructionSet(p.applicationInfo);
-            if (p.mDexOptPerformed.contains(targetInstructionSet)) {
+            if (!useProfiles && p.mDexOptPerformed.contains(targetInstructionSet)) {
+                // Skip only if we do not use profiles since they might trigger a recompilation.
                 return false;
             }
         }
@@ -6645,7 +6717,7 @@
             synchronized (mInstallLock) {
                 final String[] instructionSets = new String[] { targetInstructionSet };
                 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
-                        true /* inclDependencies */);
+                        true /* inclDependencies */, p.volumeUuid, useProfiles, extractOnly);
                 return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
             }
         } finally {
@@ -6653,20 +6725,13 @@
         }
     }
 
-    public ArraySet<String> getPackagesThatNeedDexOpt() {
-        ArraySet<String> pkgs = null;
+    public ArraySet<String> getOptimizablePackages() {
+        ArraySet<String> pkgs = new ArraySet<String>();
         synchronized (mPackages) {
             for (PackageParser.Package p : mPackages.values()) {
-                if (DEBUG_DEXOPT) {
-                    Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
+                if (PackageDexOptimizer.canOptimizePackage(p)) {
+                    pkgs.add(p.packageName);
                 }
-                if (!p.mDexOptPerformed.isEmpty()) {
-                    continue;
-                }
-                if (pkgs == null) {
-                    pkgs = new ArraySet<String>();
-                }
-                pkgs.add(p.packageName);
             }
         }
         return pkgs;
@@ -6694,8 +6759,11 @@
 
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
 
+            // 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 */);
+                    true /* inclDependencies */, pkg.volumeUuid, false /* useProfiles */,
+                    false /* extractOnly */);
 
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -6719,23 +6787,6 @@
         return true;
     }
 
-    private void createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo)
-            throws PackageManagerException {
-        // TODO: triage flags as part of 26466827
-        final int appId = UserHandle.getAppId(uid);
-        final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
-
-        try {
-            final int[] users = sUserManager.getUserIds();
-            for (int user : users) {
-                mInstaller.createAppData(volumeUuid, packageName, user, flags, appId, seinfo);
-            }
-        } catch (InstallerException e) {
-            throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
-                    "Failed to prepare data directory", e);
-        }
-    }
-
     private boolean removeDataDirsLI(String volumeUuid, String packageName) {
         // TODO: triage flags as part of 26466827
         final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
@@ -6765,6 +6816,23 @@
         }
     }
 
+    void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) {
+        try {
+            mInstaller.destroyAppData(volumeUuid, packageName, userId, flags);
+        } catch (InstallerException e) {
+            Slog.w(TAG, "Failed to destroy app data", e);
+        }
+    }
+
+    void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags,
+            int appId, String seinfo) {
+        try {
+            mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo);
+        } catch (InstallerException e) {
+            Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e);
+        }
+    }
+
     private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
         // TODO: triage flags as part of 26466827
         final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
@@ -7274,104 +7342,8 @@
                 pkg.applicationInfo.uid);
 
         if (pkg != mPlatformPackage) {
-            // This is a normal package, need to make its data directory.
-            final File dataPath = Environment.getDataUserCredentialEncryptedPackageDirectory(
-                    pkg.volumeUuid, UserHandle.USER_SYSTEM, pkg.packageName);
-
-            // TOOD: switch to ensure various directories
-
-            boolean uidError = false;
-            if (dataPath.exists()) {
-                int currentUid = 0;
-                try {
-                    StructStat stat = Os.stat(dataPath.getPath());
-                    currentUid = stat.st_uid;
-                } catch (ErrnoException e) {
-                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
-                }
-
-                // If we have mismatched owners for the data path, we have a problem.
-                if (currentUid != pkg.applicationInfo.uid) {
-                    boolean recovered = false;
-                    if (((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0
-                            || (scanFlags & SCAN_BOOTING) != 0)) {
-                        // If this is a system app, we can at least delete its
-                        // current data so the application will still work.
-                        boolean res = removeDataDirsLI(pkg.volumeUuid, pkgName);
-                        if (res) {
-                            // TODO: Kill the processes first
-                            // Old data gone!
-                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
-                                    ? "System package " : "Third party package ";
-                            String msg = prefix + pkg.packageName
-                                    + " has changed from uid: "
-                                    + currentUid + " to "
-                                    + pkg.applicationInfo.uid + "; old data erased";
-                            reportSettingsProblem(Log.WARN, msg);
-                            recovered = true;
-                        }
-                        if (!recovered) {
-                            mHasSystemUidErrors = true;
-                        }
-                    } else {
-                        // If we allow this install to proceed, we will be broken.
-                        // Abort, abort!
-                        throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
-                                "Expected data to be owned by UID " + pkg.applicationInfo.uid
-                                        + " but found " + currentUid);
-                    }
-                    if (!recovered) {
-                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
-                            + pkg.applicationInfo.uid + "/fs_"
-                            + currentUid;
-                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
-                        pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
-                        String msg = "Package " + pkg.packageName
-                                + " has mismatched uid: "
-                                + currentUid + " on disk, "
-                                + pkg.applicationInfo.uid + " in settings";
-                        // writer
-                        synchronized (mPackages) {
-                            mSettings.mReadMessages.append(msg);
-                            mSettings.mReadMessages.append('\n');
-                            uidError = true;
-                            if (!pkgSetting.uidError) {
-                                reportSettingsProblem(Log.ERROR, msg);
-                            }
-                        }
-                    }
-                }
-
-                // Ensure that directories are prepared
-                createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
-                        pkg.applicationInfo.seinfo);
-
-                if (mShouldRestoreconData) {
-                    Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
-                    // TODO: extend this to restorecon over all users
-                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
-                    // TODO: triage flags as part of 26466827
-                    final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
-                    try {
-                        mInstaller.restoreconAppData(pkg.volumeUuid, pkg.packageName,
-                                UserHandle.USER_SYSTEM, flags, appId, pkg.applicationInfo.seinfo);
-                    } catch (InstallerException e) {
-                        Slog.w(TAG, "Failed to restorecon " + pkg.packageName, e);
-                    }
-                }
-            } else {
-                if (DEBUG_PACKAGE_SCANNING) {
-                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
-                        Log.v(TAG, "Want this data dir: " + dataPath);
-                }
-                createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
-                        pkg.applicationInfo.seinfo);
-            }
-
             // Get all of our default paths setup
             pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
-
-            pkgSetting.uidError = uidError;
         }
 
         final String path = scanFile.getPath();
@@ -7405,49 +7377,6 @@
             setNativeLibraryPaths(pkg);
         }
 
-        if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
-        final int[] userIds = sUserManager.getUserIds();
-        synchronized (mInstallLock) {
-            // Make sure all user data directories are ready to roll; we're okay
-            // if they already exist
-            if (!TextUtils.isEmpty(pkg.volumeUuid)) {
-                for (int userId : userIds) {
-                    if (userId != UserHandle.USER_SYSTEM) {
-                        // TODO: triage flags as part of 26466827
-                        final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
-                        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
-                        try {
-                            mInstaller.createAppData(pkg.volumeUuid, pkg.packageName, userId,
-                                    flags, appId, pkg.applicationInfo.seinfo);
-                        } catch (InstallerException e) {
-                            throw PackageManagerException.from(e);
-                        }
-                    }
-                }
-            }
-
-            // Create a native library symlink only if we have native libraries
-            // and if the native libraries are 32 bit libraries. We do not provide
-            // this symlink for 64 bit libraries.
-            if (pkg.applicationInfo.primaryCpuAbi != null &&
-                    !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
-                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "linkNativeLib");
-                try {
-                    final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
-                    for (int userId : userIds) {
-                        try {
-                            mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
-                                    nativeLibPath, userId);
-                        } catch (InstallerException e) {
-                            throw PackageManagerException.from(e);
-                        }
-                    }
-                } finally {
-                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-                }
-            }
-        }
-
         // This is a special case for the "system" package, where the ABI is
         // dictated by the zygote configuration (and init.rc). We should keep track
         // of this ABI so that we can deal with "normal" applications that run under
@@ -10174,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.
@@ -10216,7 +10158,7 @@
 
         long callingId = Binder.clearCallingIdentity();
         try {
-            boolean sendAdded = false;
+            boolean installed = false;
 
             // writer
             synchronized (mPackages) {
@@ -10228,11 +10170,14 @@
                     pkgSetting.setInstalled(true, userId);
                     pkgSetting.setHidden(false, userId);
                     mSettings.writePackageRestrictionsLPr(userId);
-                    sendAdded = true;
+                    if (pkgSetting.pkg != null) {
+                        prepareAppDataAfterInstall(pkgSetting.pkg);
+                    }
+                    installed = true;
                 }
             }
 
-            if (sendAdded) {
+            if (installed) {
                 sendPackageAddedForUser(packageName, pkgSetting, userId);
             }
         } finally {
@@ -10257,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);
         }
@@ -10997,9 +10956,10 @@
         final String dataAppName;
         final int appId;
         final String seinfo;
+        final int targetSdkVersion;
 
         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
-                String dataAppName, int appId, String seinfo) {
+                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
             this.moveId = moveId;
             this.fromUuid = fromUuid;
             this.toUuid = toUuid;
@@ -11007,6 +10967,7 @@
             this.dataAppName = dataAppName;
             this.appId = appId;
             this.seinfo = seinfo;
+            this.targetSdkVersion = targetSdkVersion;
         }
     }
 
@@ -12129,7 +12090,7 @@
             synchronized (mInstaller) {
                 try {
                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
-                            move.dataAppName, move.appId, move.seinfo);
+                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
                 } catch (InstallerException e) {
                     Slog.w(TAG, "Failed to move app", e);
                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
@@ -12358,6 +12319,8 @@
                     System.currentTimeMillis(), user);
 
             updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
+            prepareAppDataAfterInstall(newPackage);
+
             // delete the partially installed application. the data directory will have to be
             // restored if it was already existing
             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
@@ -12514,6 +12477,7 @@
                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
                 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
                         perUserInstalled, res, user);
+                prepareAppDataAfterInstall(newPackage);
                 updatedSettings = true;
             } catch (PackageManagerException e) {
                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
@@ -12645,6 +12609,7 @@
             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
                         perUserInstalled, res, user);
+                prepareAppDataAfterInstall(newPackage);
                 updatedSettings = true;
             }
 
@@ -13050,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 */, volumeUuid, 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)) {
@@ -13682,6 +13665,8 @@
             return false;
         }
 
+        prepareAppDataAfterInstall(newPkg);
+
         // writer
         synchronized (mPackages) {
             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
@@ -14813,7 +14798,7 @@
             }
             return;
         }
-
+Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
         // this is supposed to be TAG_PREFERRED_BACKUP
         if (!expectedStartTag.equals(parser.getName())) {
             if (DEBUG_BACKUP) {
@@ -14824,6 +14809,7 @@
 
         // skip interfering stuff, then we're aligned with the backing implementation
         while ((type = parser.next()) == XmlPullParser.TEXT) { }
+Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
         functor.apply(parser, userId);
     }
 
@@ -15011,6 +14997,192 @@
     }
 
     @Override
+    public byte[] getPermissionGrantBackup(int userId) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
+        }
+
+        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+        try {
+            final XmlSerializer serializer = new FastXmlSerializer();
+            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
+            serializer.startDocument(null, true);
+            serializer.startTag(null, TAG_PERMISSION_BACKUP);
+
+            synchronized (mPackages) {
+                serializeRuntimePermissionGrantsLPr(serializer, userId);
+            }
+
+            serializer.endTag(null, TAG_PERMISSION_BACKUP);
+            serializer.endDocument();
+            serializer.flush();
+        } catch (Exception e) {
+            if (DEBUG_BACKUP) {
+                Slog.e(TAG, "Unable to write default apps for backup", e);
+            }
+            return null;
+        }
+
+        return dataStream.toByteArray();
+    }
+
+    @Override
+    public void restorePermissionGrants(byte[] backup, int userId) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("Only the system may call restorePermissionGrants()");
+        }
+
+        try {
+            final XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
+            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
+                    new BlobXmlRestorer() {
+                        @Override
+                        public void apply(XmlPullParser parser, int userId)
+                                throws XmlPullParserException, IOException {
+                            synchronized (mPackages) {
+                                processRestoredPermissionGrantsLPr(parser, userId);
+                            }
+                        }
+                    } );
+        } catch (Exception e) {
+            if (DEBUG_BACKUP) {
+                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
+            }
+        }
+    }
+
+    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
+            throws IOException {
+        serializer.startTag(null, TAG_ALL_GRANTS);
+
+        final int N = mSettings.mPackages.size();
+        for (int i = 0; i < N; i++) {
+            final PackageSetting ps = mSettings.mPackages.valueAt(i);
+            boolean pkgGrantsKnown = false;
+
+            PermissionsState packagePerms = ps.getPermissionsState();
+
+            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
+                final int grantFlags = state.getFlags();
+                // only look at grants that are not system/policy fixed
+                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
+                    final boolean isGranted = state.isGranted();
+                    // And only back up the user-twiddled state bits
+                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
+                        final String packageName = mSettings.mPackages.keyAt(i);
+                        if (!pkgGrantsKnown) {
+                            serializer.startTag(null, TAG_GRANT);
+                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
+                            pkgGrantsKnown = true;
+                        }
+
+                        final boolean userSet =
+                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
+                        final boolean userFixed =
+                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
+                        final boolean revoke =
+                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
+
+                        serializer.startTag(null, TAG_PERMISSION);
+                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
+                        if (isGranted) {
+                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
+                        }
+                        if (userSet) {
+                            serializer.attribute(null, ATTR_USER_SET, "true");
+                        }
+                        if (userFixed) {
+                            serializer.attribute(null, ATTR_USER_FIXED, "true");
+                        }
+                        if (revoke) {
+                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
+                        }
+                        serializer.endTag(null, TAG_PERMISSION);
+                    }
+                }
+            }
+
+            if (pkgGrantsKnown) {
+                serializer.endTag(null, TAG_GRANT);
+            }
+        }
+
+        serializer.endTag(null, TAG_ALL_GRANTS);
+    }
+
+    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
+            throws XmlPullParserException, IOException {
+        String pkgName = null;
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+
+            final String tagName = parser.getName();
+            if (tagName.equals(TAG_GRANT)) {
+                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
+                if (DEBUG_BACKUP) {
+                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
+                }
+            } else if (tagName.equals(TAG_PERMISSION)) {
+
+                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
+                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
+
+                int newFlagSet = 0;
+                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
+                    newFlagSet |= FLAG_PERMISSION_USER_SET;
+                }
+                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
+                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
+                }
+                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
+                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+                }
+                if (DEBUG_BACKUP) {
+                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
+                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
+                }
+                final PackageSetting ps = mSettings.mPackages.get(pkgName);
+                if (ps != null) {
+                    // Already installed so we apply the grant immediately
+                    if (DEBUG_BACKUP) {
+                        Slog.v(TAG, "        + already installed; applying");
+                    }
+                    PermissionsState perms = ps.getPermissionsState();
+                    BasePermission bp = mSettings.mPermissions.get(permName);
+                    if (bp != null) {
+                        if (isGranted) {
+                            perms.grantRuntimePermission(bp, userId);
+                        }
+                        if (newFlagSet != 0) {
+                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
+                        }
+                    }
+                } else {
+                    // Need to wait for post-restore install to apply the grant
+                    if (DEBUG_BACKUP) {
+                        Slog.v(TAG, "        - not yet installed; saving for later");
+                    }
+                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
+                            isGranted, newFlagSet, userId);
+                }
+            } else {
+                PackageManagerService.reportSettingsProblem(Log.WARN,
+                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+
+        scheduleWriteSettingsLocked();
+        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
+    }
+
+    @Override
     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
             int sourceUserId, int targetUserId, int flags) {
         mContext.enforceCallingOrSelfPermission(
@@ -16022,6 +16194,10 @@
                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
             }
 
+            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
+                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
+            }
+
             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
                 // XXX should handle packageName != null by dumping only install data that
                 // the given package is involved with.
@@ -16169,10 +16345,6 @@
      */
     public void scanAvailableAsecs() {
         updateExternalMediaStatusInner(true, false, false);
-        if (mShouldRestoreconData) {
-            SELinuxMMAC.setRestoreconDone();
-            mShouldRestoreconData = false;
-        }
     }
 
     /*
@@ -16493,22 +16665,31 @@
     }
 
     private void loadPrivatePackagesInner(VolumeInfo vol) {
+        final String volumeUuid = vol.fsUuid;
+        if (TextUtils.isEmpty(volumeUuid)) {
+            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
+            return;
+        }
+
         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
 
         final VersionInfo ver;
         final List<PackageSetting> packages;
         synchronized (mPackages) {
-            ver = mSettings.findOrCreateVersion(vol.fsUuid);
-            packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
+            ver = mSettings.findOrCreateVersion(volumeUuid);
+            packages = mSettings.getVolumePackagesLPr(volumeUuid);
         }
 
+        // TODO: introduce a new concept similar to "frozen" to prevent these
+        // apps from being launched until after data has been fully reconciled
         for (PackageSetting ps : packages) {
             synchronized (mInstallLock) {
                 final PackageParser.Package pkg;
                 try {
                     pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
                     loaded.add(pkg.applicationInfo);
+
                 } catch (PackageManagerException e) {
                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
                 }
@@ -16519,14 +16700,27 @@
             }
         }
 
+        // Reconcile app data for all started/unlocked users
+        final UserManager um = mContext.getSystemService(UserManager.class);
+        for (UserInfo user : um.getUsers()) {
+            if (um.isUserUnlocked(user.id)) {
+                reconcileAppsData(volumeUuid, user.id,
+                        Installer.FLAG_DE_STORAGE | Installer.FLAG_CE_STORAGE);
+            } else if (um.isUserRunning(user.id)) {
+                reconcileAppsData(volumeUuid, user.id, Installer.FLAG_DE_STORAGE);
+            } else {
+                continue;
+            }
+        }
+
         synchronized (mPackages) {
             int updateFlags = UPDATE_PERMISSIONS_ALL;
             if (ver.sdkVersion != mSdkVersion) {
                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
-                        + mSdkVersion + "; regranting permissions for " + vol.fsUuid);
+                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
             }
-            updatePermissionsLPw(null, null, vol.fsUuid, updateFlags);
+            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
 
             // Yay, everything is now upgraded
             ver.forceCurrent();
@@ -16548,10 +16742,16 @@
     }
 
     private void unloadPrivatePackagesInner(VolumeInfo vol) {
+        final String volumeUuid = vol.fsUuid;
+        if (TextUtils.isEmpty(volumeUuid)) {
+            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
+            return;
+        }
+
         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
         synchronized (mInstallLock) {
         synchronized (mPackages) {
-            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
+            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
             for (PackageSetting ps : packages) {
                 if (ps.pkg == null) continue;
 
@@ -16635,6 +16835,37 @@
         }
     }
 
+    private void assertPackageKnown(String volumeUuid, String packageName)
+            throws PackageManagerException {
+        synchronized (mPackages) {
+            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            if (ps == null) {
+                throw new PackageManagerException("Package " + packageName + " is unknown");
+            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
+                throw new PackageManagerException(
+                        "Package " + packageName + " found on unknown volume " + volumeUuid
+                                + "; expected volume " + ps.volumeUuid);
+            }
+        }
+    }
+
+    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
+            throws PackageManagerException {
+        synchronized (mPackages) {
+            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            if (ps == null) {
+                throw new PackageManagerException("Package " + packageName + " is unknown");
+            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
+                throw new PackageManagerException(
+                        "Package " + packageName + " found on unknown volume " + volumeUuid
+                                + "; expected volume " + ps.volumeUuid);
+            } else if (!ps.getInstalled(userId)) {
+                throw new PackageManagerException(
+                        "Package " + packageName + " not installed for user " + userId);
+            }
+        }
+    }
+
     /**
      * Examine all apps present on given mounted volume, and destroy apps that
      * aren't expected, either due to uninstallation or reinstallation on
@@ -16651,37 +16882,223 @@
                 continue;
             }
 
-            boolean destroyApp = false;
-            String packageName = null;
             try {
                 final PackageLite pkg = PackageParser.parsePackageLite(file,
                         PackageParser.PARSE_MUST_BE_APK);
-                packageName = pkg.packageName;
+                assertPackageKnown(volumeUuid, pkg.packageName);
 
-                synchronized (mPackages) {
-                    final PackageSetting ps = mSettings.mPackages.get(packageName);
-                    if (ps == null) {
-                        logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + "
-                                + volumeUuid + " because we found no install record");
-                        destroyApp = true;
-                    } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
-                        logCriticalInfo(Log.WARN, "Destroying " + packageName + " on "
-                                + volumeUuid + " because we expected it on " + ps.volumeUuid);
-                        destroyApp = true;
-                    }
+            } catch (PackageParserException | PackageManagerException e) {
+                logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
+                synchronized (mInstallLock) {
+                    removeCodePathLI(file);
                 }
+            }
+        }
+    }
 
-            } catch (PackageParserException e) {
-                logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e);
-                destroyApp = true;
+    /**
+     * Reconcile all app data for the given user.
+     * <p>
+     * Verifies that directories exist and that ownership and labeling is
+     * correct for all installed apps on all mounted volumes.
+     */
+    void reconcileAppsData(int userId, @StorageFlags int flags) {
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+            final String volumeUuid = vol.getFsUuid();
+            reconcileAppsData(volumeUuid, userId, flags);
+        }
+    }
+
+    /**
+     * Reconcile all app data on given mounted volume.
+     * <p>
+     * Destroys app data that isn't expected, either due to uninstallation or
+     * reinstallation on another volume.
+     * <p>
+     * Verifies that directories exist and that ownership and labeling is
+     * correct for all installed apps.
+     */
+    private void reconcileAppsData(String volumeUuid, int userId, @StorageFlags int flags) {
+        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
+                + Integer.toHexString(flags));
+
+        final File ceDir = Environment.getDataUserCredentialEncryptedDirectory(volumeUuid, userId);
+        final File deDir = Environment.getDataUserDeviceEncryptedDirectory(volumeUuid, userId);
+
+        boolean restoreconNeeded = false;
+
+        // First look for stale data that doesn't belong, and check if things
+        // have changed since we did our last restorecon
+        if ((flags & Installer.FLAG_CE_STORAGE) != 0) {
+            if (!isUserKeyUnlocked(userId)) {
+                throw new RuntimeException(
+                        "Yikes, someone asked us to reconcile CE storage while " + userId
+                                + " was still locked; this would have caused massive data loss!");
             }
 
-            if (destroyApp) {
-                synchronized (mInstallLock) {
-                    if (packageName != null) {
-                        removeDataDirsLI(volumeUuid, packageName);
+            restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir);
+
+            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
+            for (File file : files) {
+                final String packageName = file.getName();
+                try {
+                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
+                } catch (PackageManagerException e) {
+                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
+                    synchronized (mInstallLock) {
+                        destroyAppDataLI(volumeUuid, packageName, userId,
+                                Installer.FLAG_CE_STORAGE);
                     }
-                    removeCodePathLI(file);
+                }
+            }
+        }
+        if ((flags & Installer.FLAG_DE_STORAGE) != 0) {
+            restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir);
+
+            final File[] files = FileUtils.listFilesOrEmpty(deDir);
+            for (File file : files) {
+                final String packageName = file.getName();
+                try {
+                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
+                } catch (PackageManagerException e) {
+                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
+                    synchronized (mInstallLock) {
+                        destroyAppDataLI(volumeUuid, packageName, userId,
+                                Installer.FLAG_DE_STORAGE);
+                    }
+                }
+            }
+        }
+
+        // Ensure that data directories are ready to roll for all packages
+        // installed for this volume and user
+        final List<PackageSetting> packages;
+        synchronized (mPackages) {
+            packages = mSettings.getVolumePackagesLPr(volumeUuid);
+        }
+        int preparedCount = 0;
+        for (PackageSetting ps : packages) {
+            final String packageName = ps.name;
+            if (ps.pkg == null) {
+                Slog.w(TAG, "Odd, missing scanned package " + packageName);
+                // TODO: might be due to legacy ASEC apps; we should circle back
+                // and reconcile again once they're scanned
+                continue;
+            }
+
+            if (ps.getInstalled(userId)) {
+                prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
+                preparedCount++;
+            }
+        }
+
+        if (restoreconNeeded) {
+            if ((flags & Installer.FLAG_CE_STORAGE) != 0) {
+                SELinuxMMAC.setRestoreconDone(ceDir);
+            }
+            if ((flags & Installer.FLAG_DE_STORAGE) != 0) {
+                SELinuxMMAC.setRestoreconDone(deDir);
+            }
+        }
+
+        Slog.v(TAG, "reconcileAppsData finished " + preparedCount
+                + " packages; restoreconNeeded was " + restoreconNeeded);
+    }
+
+    /**
+     * Prepare app data for the given app just after it was installed or
+     * upgraded. This method carefully only touches users that it's installed
+     * for, and it forces a restorecon to handle any seinfo changes.
+     * <p>
+     * Verifies that directories exist and that ownership and labeling is
+     * correct for all installed apps. If there is an ownership mismatch, it
+     * will try recovering system apps by wiping data; third-party app data is
+     * left intact.
+     */
+    private void prepareAppDataAfterInstall(PackageParser.Package pkg) {
+        final PackageSetting ps;
+        synchronized (mPackages) {
+            ps = mSettings.mPackages.get(pkg.packageName);
+        }
+
+        final UserManager um = mContext.getSystemService(UserManager.class);
+        for (UserInfo user : um.getUsers()) {
+            final int flags;
+            if (um.isUserUnlocked(user.id)) {
+                flags = Installer.FLAG_DE_STORAGE | Installer.FLAG_CE_STORAGE;
+            } else if (um.isUserRunning(user.id)) {
+                flags = Installer.FLAG_DE_STORAGE;
+            } else {
+                continue;
+            }
+
+            if (ps.getInstalled(user.id)) {
+                // Whenever an app changes, force a restorecon of its data
+                // TODO: when user data is locked, mark that we're still dirty
+                prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true);
+            }
+        }
+    }
+
+    /**
+     * Prepare app data for the given app.
+     * <p>
+     * Verifies that directories exist and that ownership and labeling is
+     * correct for all installed apps. If there is an ownership mismatch, this
+     * will try recovering system apps by wiping data; third-party app data is
+     * left intact.
+     */
+    private void prepareAppData(String volumeUuid, int userId, @StorageFlags int flags,
+            PackageParser.Package pkg, boolean restoreconNeeded) {
+        if (DEBUG_APP_DATA) {
+            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
+                    + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : ""));
+        }
+
+        final String packageName = pkg.packageName;
+        final ApplicationInfo app = pkg.applicationInfo;
+        final int appId = UserHandle.getAppId(app.uid);
+
+        Preconditions.checkNotNull(app.seinfo);
+
+        synchronized (mInstallLock) {
+            try {
+                mInstaller.createAppData(volumeUuid, packageName, userId, flags,
+                        appId, app.seinfo, app.targetSdkVersion);
+            } catch (InstallerException e) {
+                if (app.isSystemApp()) {
+                    logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
+                            + ", but trying to recover: " + e);
+                    destroyAppDataLI(volumeUuid, packageName, userId, flags);
+                    try {
+                        mInstaller.createAppData(volumeUuid, packageName, userId, flags,
+                                appId, app.seinfo, app.targetSdkVersion);
+                        logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
+                    } catch (InstallerException e2) {
+                        logCriticalInfo(Log.DEBUG, "Recovery failed!");
+                    }
+                } else {
+                    Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
+                }
+            }
+
+            if (restoreconNeeded) {
+                restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo);
+            }
+
+            if ((flags & Installer.FLAG_CE_STORAGE) != 0) {
+                // Create a native library symlink only if we have native libraries
+                // and if the native libraries are 32 bit libraries. We do not provide
+                // this symlink for 64 bit libraries.
+                if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
+                    final String nativeLibPath = app.nativeLibraryDir;
+                    try {
+                        mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
+                                nativeLibPath, userId);
+                    } catch (InstallerException e) {
+                        Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
+                    }
                 }
             }
         }
@@ -16730,6 +17147,7 @@
         final int appId;
         final String seinfo;
         final String label;
+        final int targetSdkVersion;
 
         // reader
         synchronized (mPackages) {
@@ -16779,6 +17197,7 @@
             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
             seinfo = pkg.applicationInfo.seinfo;
             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
+            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
         }
 
         // Now that we're guarded by frozen state, kill app during move
@@ -16911,7 +17330,7 @@
 
             final String dataAppName = codeFile.getName();
             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
-                    dataAppName, appId, seinfo);
+                    dataAppName, appId, seinfo, targetSdkVersion);
         } else {
             move = null;
         }
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 903d12b..aa10c08 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -19,20 +19,24 @@
 import android.content.pm.PackageParser;
 import android.content.pm.Signature;
 import android.os.Environment;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 import android.util.Slog;
 import android.util.Xml;
 
 import libcore.io.IoUtils;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
-
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -41,9 +45,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 /**
  * Centralized access to SELinux MMAC (middleware MAC) implementation. This
  * class is responsible for loading the appropriate mac_permissions.xml file
@@ -63,42 +64,21 @@
     // to synchronize access during policy load and access attempts.
     private static List<Policy> sPolicies = new ArrayList<>();
 
-    // Data policy override version file.
-    private static final String DATA_VERSION_FILE =
-            Environment.getDataDirectory() + "/security/current/selinux_version";
+    /** Path to version on rootfs */
+    private static final File VERSION_FILE = new File("/selinux_version");
 
-    // Base policy version file.
-    private static final String BASE_VERSION_FILE = "/selinux_version";
+    /** Path to MAC permissions on system image */
+    private static final File MAC_PERMISSIONS = new File(Environment.getRootDirectory(),
+            "/etc/security/mac_permissions.xml");
 
-    // Whether override security policies should be loaded.
-    private static final boolean USE_OVERRIDE_POLICY = useOverridePolicy();
+    /** Path to app contexts on rootfs */
+    private static final File SEAPP_CONTEXTS = new File("/seapp_contexts");
 
-    // Data override mac_permissions.xml policy file.
-    private static final String DATA_MAC_PERMISSIONS =
-            Environment.getDataDirectory() + "/security/current/mac_permissions.xml";
+    /** Calculated hash of {@link #SEAPP_CONTEXTS} */
+    private static final byte[] SEAPP_CONTEXTS_HASH = returnHash(SEAPP_CONTEXTS);
 
-    // Base mac_permissions.xml policy file.
-    private static final String BASE_MAC_PERMISSIONS =
-            Environment.getRootDirectory() + "/etc/security/mac_permissions.xml";
-
-    // Determine which mac_permissions.xml file to use.
-    private static final String MAC_PERMISSIONS = USE_OVERRIDE_POLICY ?
-            DATA_MAC_PERMISSIONS : BASE_MAC_PERMISSIONS;
-
-    // Data override seapp_contexts policy file.
-    private static final String DATA_SEAPP_CONTEXTS =
-            Environment.getDataDirectory() + "/security/current/seapp_contexts";
-
-    // Base seapp_contexts policy file.
-    private static final String BASE_SEAPP_CONTEXTS = "/seapp_contexts";
-
-    // Determine which seapp_contexts file to use.
-    private static final String SEAPP_CONTEXTS = USE_OVERRIDE_POLICY ?
-            DATA_SEAPP_CONTEXTS : BASE_SEAPP_CONTEXTS;
-
-    // Stores the hash of the last used seapp_contexts file.
-    private static final String SEAPP_HASH_FILE =
-            Environment.getDataDirectory().toString() + "/system/seapp_hash";
+    /** Attribute where {@link #SEAPP_CONTEXTS_HASH} is stored */
+    private static final String XATTR_SEAPP_HASH = "user.seapp_hash";
 
     // Append privapp to existing seinfo label
     private static final String PRIVILEGED_APP_STR = ":privapp";
@@ -332,71 +312,42 @@
     }
 
     /**
-     * Determines if a recursive restorecon on /data/data and /data/user is needed.
-     * It does this by comparing the SHA-1 of the seapp_contexts file against the
-     * stored hash at /data/system/seapp_hash.
+     * Determines if a recursive restorecon on the given package data directory
+     * is needed. It does this by comparing the SHA-1 of the seapp_contexts file
+     * against the stored hash in an xattr.
+     * <p>
+     * Note that the xattr isn't in the 'security' namespace, so this should
+     * only be run on directories owned by the system.
      *
      * @return Returns true if the restorecon should occur or false otherwise.
      */
-    public static boolean shouldRestorecon() {
-        // Any error with the seapp_contexts file should be fatal
-        byte[] currentHash = null;
+    public static boolean isRestoreconNeeded(File file) {
         try {
-            currentHash = returnHash(SEAPP_CONTEXTS);
-        } catch (IOException ioe) {
-            Slog.e(TAG, "Error with hashing seapp_contexts.", ioe);
-            return false;
+            final byte[] buf = new byte[20];
+            final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH, buf);
+            if ((len == 20) && Arrays.equals(SEAPP_CONTEXTS_HASH, buf)) {
+                return false;
+            }
+        } catch (ErrnoException e) {
+            if (e.errno != OsConstants.ENODATA) {
+                Slog.e(TAG, "Failed to read seapp hash for " + file, e);
+            }
         }
 
-        // Push past any error with the stored hash file
-        byte[] storedHash = null;
-        try {
-            storedHash = IoUtils.readFileAsByteArray(SEAPP_HASH_FILE);
-        } catch (IOException ioe) {
-            Slog.w(TAG, "Error opening " + SEAPP_HASH_FILE + ". Assuming first boot.");
-        }
-
-        return (storedHash == null || !MessageDigest.isEqual(storedHash, currentHash));
+        return true;
     }
 
     /**
-     * Stores the SHA-1 of the seapp_contexts to /data/system/seapp_hash.
+     * Stores the SHA-1 of the seapp_contexts into an xattr.
+     * <p>
+     * Note that the xattr isn't in the 'security' namespace, so this should
+     * only be run on directories owned by the system.
      */
-    public static void setRestoreconDone() {
+    public static void setRestoreconDone(File file) {
         try {
-            final byte[] currentHash = returnHash(SEAPP_CONTEXTS);
-            dumpHash(new File(SEAPP_HASH_FILE), currentHash);
-        } catch (IOException ioe) {
-            Slog.e(TAG, "Error with saving hash to " + SEAPP_HASH_FILE, ioe);
-        }
-    }
-
-    /**
-     * Dump the contents of a byte array to a specified file.
-     *
-     * @param file The file that receives the byte array content.
-     * @param content A byte array that will be written to the specified file.
-     * @throws IOException if any failed I/O operation occured.
-     *         Included is the failure to atomically rename the tmp
-     *         file used in the process.
-     */
-    private static void dumpHash(File file, byte[] content) throws IOException {
-        FileOutputStream fos = null;
-        File tmp = null;
-        try {
-            tmp = File.createTempFile("seapp_hash", ".journal", file.getParentFile());
-            tmp.setReadable(true);
-            fos = new FileOutputStream(tmp);
-            fos.write(content);
-            fos.getFD().sync();
-            if (!tmp.renameTo(file)) {
-                throw new IOException("Failure renaming " + file.getCanonicalPath());
-            }
-        } finally {
-            if (tmp != null) {
-                tmp.delete();
-            }
-            IoUtils.closeQuietly(fos);
+            Os.setxattr(file.getAbsolutePath(), XATTR_SEAPP_HASH, SEAPP_CONTEXTS_HASH, 0);
+        } catch (ErrnoException e) {
+            Slog.e(TAG, "Failed to persist seapp hash in " + file, e);
         }
     }
 
@@ -405,33 +356,15 @@
      *
      * @param file The path to the file given as a string.
      * @return Returns the SHA-1 of the file as a byte array.
-     * @throws IOException if any failed I/O operations occured.
      */
-    private static byte[] returnHash(String file) throws IOException {
+    private static byte[] returnHash(File file) {
         try {
-            final byte[] contents = IoUtils.readFileAsByteArray(file);
+            final byte[] contents = IoUtils.readFileAsByteArray(file.getAbsolutePath());
             return MessageDigest.getInstance("SHA-1").digest(contents);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new RuntimeException(nsae);  // impossible
+        } catch (IOException | NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
         }
     }
-
-    private static boolean useOverridePolicy() {
-        try {
-            final String overrideVersion = IoUtils.readFileAsString(DATA_VERSION_FILE);
-            final String baseVersion = IoUtils.readFileAsString(BASE_VERSION_FILE);
-            if (overrideVersion.equals(baseVersion)) {
-                return true;
-            }
-            Slog.e(TAG, "Override policy version '" + overrideVersion + "' doesn't match " +
-                   "base version '" + baseVersion + "'. Skipping override policy files.");
-        } catch (FileNotFoundException fnfe) {
-            // Override version file doesn't have to exist so silently ignore.
-        } catch (IOException ioe) {
-            Slog.w(TAG, "Skipping override policy files.", ioe);
-        }
-        return false;
-    }
 }
 
 /**
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 9fef515..bbbe693 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -22,6 +22,9 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
 import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
@@ -32,7 +35,6 @@
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.os.Process.PACKAGE_INFO_GID;
 import static android.os.Process.SYSTEM_UID;
-
 import static com.android.server.pm.PackageManagerService.DEBUG_DOMAIN_VERIFICATION;
 
 import android.annotation.NonNull;
@@ -217,6 +219,22 @@
     private static final String ATTR_SDK_VERSION = "sdkVersion";
     private static final String ATTR_DATABASE_VERSION = "databaseVersion";
 
+    // Bookkeeping for restored permission grants
+    private static final String TAG_RESTORED_RUNTIME_PERMISSIONS = "restored-perms";
+    // package name: ATTR_PACKAGE_NAME
+    private static final String TAG_PERMISSION_ENTRY = "perm";
+    // permission name: ATTR_NAME
+    // permission granted (boolean): ATTR_GRANTED
+    private static final String ATTR_USER_SET = "set";
+    private static final String ATTR_USER_FIXED = "fixed";
+    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
+
+    // Flag mask of restored permission grants that are applied at install time
+    private static final int USER_RUNTIME_GRANT_MASK =
+            FLAG_PERMISSION_USER_SET
+            | FLAG_PERMISSION_USER_FIXED
+            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+
     private final Object mLock;
 
     private final RuntimePermissionPersistence mRuntimePermissionsPersistence;
@@ -238,6 +256,26 @@
     private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
             new ArrayMap<String, IntentFilterVerificationInfo>();
 
+    // Bookkeeping for restored user permission grants
+    final class RestoredPermissionGrant {
+        String permissionName;
+        boolean granted;
+        int grantBits;
+
+        RestoredPermissionGrant(String name, boolean isGranted, int theGrantBits) {
+            permissionName = name;
+            granted = isGranted;
+            grantBits = theGrantBits;
+        }
+    }
+
+    // This would be more compact as a flat array of restored grants or something, but we
+    // may have quite a few, especially during early device lifetime, and avoiding all those
+    // linear lookups will be important.
+    private final SparseArray<ArrayMap<String, ArraySet<RestoredPermissionGrant>>>
+            mRestoredUserGrants =
+                new SparseArray<ArrayMap<String, ArraySet<RestoredPermissionGrant>>>();
+
     private static int mFirstAvailableUid = 0;
 
     /** Map from volume UUID to {@link VersionInfo} */
@@ -388,7 +426,7 @@
         return mPackages.get(name);
     }
 
-    void setInstallStatus(String pkgName, int status) {
+    void setInstallStatus(String pkgName, final int status) {
         PackageSetting p = mPackages.get(pkgName);
         if(p != null) {
             if(p.getInstallStatus() != status) {
@@ -397,6 +435,43 @@
         }
     }
 
+    void applyPendingPermissionGrantsLPw(String packageName, int userId) {
+        ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
+                mRestoredUserGrants.get(userId);
+        if (grantsByPackage == null || grantsByPackage.size() == 0) {
+            return;
+        }
+
+        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(packageName);
+        if (grants == null || grants.size() == 0) {
+            return;
+        }
+
+        final PackageSetting ps = mPackages.get(packageName);
+        if (ps == null) {
+            Slog.e(TAG, "Can't find supposedly installed package " + packageName);
+            return;
+        }
+        final PermissionsState perms = ps.getPermissionsState();
+
+        for (RestoredPermissionGrant grant : grants) {
+            BasePermission bp = mPermissions.get(grant.permissionName);
+            if (bp != null) {
+                if (grant.granted) {
+                    perms.grantRuntimePermission(bp, userId);
+                }
+                perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, grant.grantBits);
+            }
+        }
+
+        // And remove it from the pending-grant bookkeeping
+        grantsByPackage.remove(packageName);
+        if (grantsByPackage.size() < 1) {
+            mRestoredUserGrants.remove(userId);
+        }
+        writeRuntimePermissionsForUserLPr(userId, false);
+    }
+
     void setInstallerPackageName(String pkgName, String installerPkgName) {
         PackageSetting p = mPackages.get(pkgName);
         if (p != null) {
@@ -1725,6 +1800,14 @@
         }
     }
 
+    // Specifically for backup/restore
+    public void processRestoredPermissionGrantLPr(String pkgName, String permission,
+            boolean isGranted, int restoredFlagSet, int userId)
+            throws IOException, XmlPullParserException {
+        mRuntimePermissionsPersistence.rememberRestoredUserGrantLPr(
+                pkgName, permission, isGranted, restoredFlagSet, userId);
+    }
+
     void writeDefaultAppsLPr(XmlSerializer serializer, int userId)
             throws IllegalArgumentException, IllegalStateException, IOException {
         serializer.startTag(null, TAG_DEFAULT_APPS);
@@ -2962,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
@@ -3671,6 +3755,7 @@
         String[] names;
         int[] appIds;
         String[] seinfos;
+        int[] targetSdkVersions;
         int packagesCount;
         synchronized (mPackages) {
             Collection<PackageSetting> packages = mPackages.values();
@@ -3679,6 +3764,7 @@
             names = new String[packagesCount];
             appIds = new int[packagesCount];
             seinfos = new String[packagesCount];
+            targetSdkVersions = new int[packagesCount];
             Iterator<PackageSetting> packagesIterator = packages.iterator();
             for (int i = 0; i < packagesCount; i++) {
                 PackageSetting ps = packagesIterator.next();
@@ -3693,6 +3779,7 @@
                 names[i] = ps.name;
                 appIds[i] = ps.appId;
                 seinfos[i] = ps.pkg.applicationInfo.seinfo;
+                targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
             }
         }
         for (int i = 0; i < packagesCount; i++) {
@@ -3703,7 +3790,7 @@
             final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
             try {
                 installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],
-                        seinfos[i]);
+                        seinfos[i], targetSdkVersions[i]);
             } catch (InstallerException e) {
                 Slog.w(TAG, "Failed to prepare app data", e);
             }
@@ -3893,7 +3980,6 @@
      * given {@link VolumeInfo#fsUuid}.
      */
     List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
-        Preconditions.checkNotNull(volumeUuid);
         ArrayList<PackageSetting> res = new ArrayList<>();
         for (int i = 0; i < mPackages.size(); i++) {
             final PackageSetting setting = mPackages.valueAt(i);
@@ -4410,6 +4496,48 @@
         pw.print(mReadMessages.toString());
     }
 
+    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
+        if (mRestoredUserGrants.size() > 0) {
+            pw.println();
+            pw.println("Restored (pending) permission grants:");
+            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
+                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
+                        mRestoredUserGrants.valueAt(userIndex);
+                if (grantsByPackage != null && grantsByPackage.size() > 0) {
+                    final int userId = mRestoredUserGrants.keyAt(userIndex);
+                    pw.print("  User "); pw.println(userId);
+
+                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
+                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
+                        if (grants != null && grants.size() > 0) {
+                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
+                            pw.print("    "); pw.print(pkgName); pw.println(" :");
+
+                            for (RestoredPermissionGrant g : grants) {
+                                pw.print("      ");
+                                pw.print(g.permissionName);
+                                if (g.granted) {
+                                    pw.print(" GRANTED");
+                                }
+                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
+                                    pw.print(" user_set");
+                                }
+                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
+                                    pw.print(" user_fixed");
+                                }
+                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
+                                    pw.print(" revoke_on_upgrade");
+                                }
+                                pw.println();
+                            }
+                        }
+                    }
+                }
+            }
+            pw.println();
+        }
+    }
+
     private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
         if (pkg == null) {
             pw.print("unknown");
@@ -4507,7 +4635,6 @@
 
     private final class RuntimePermissionPersistence {
         private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
-
         private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
 
         private final Handler mHandler = new MyHandler();
@@ -4624,6 +4751,7 @@
                 serializer.setFeature(
                         "http://xmlpull.org/v1/doc/features.html#indent-output", true);
                 serializer.startDocument(null, true);
+
                 serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
 
                 String fingerprint = mFingerprints.get(userId);
@@ -4652,6 +4780,51 @@
                 }
 
                 serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
+
+                // Now any restored permission grants that are waiting for the apps
+                // in question to be installed.  These are stored as per-package
+                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
+                // number of individual permission grant entities.
+                if (mRestoredUserGrants.get(userId) != null) {
+                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
+                            mRestoredUserGrants.get(userId);
+                    if (restoredGrants != null) {
+                        final int pkgCount = restoredGrants.size();
+                        for (int i = 0; i < pkgCount; i++) {
+                            final ArraySet<RestoredPermissionGrant> pkgGrants =
+                                    restoredGrants.valueAt(i);
+                            if (pkgGrants != null && pkgGrants.size() > 0) {
+                                final String pkgName = restoredGrants.keyAt(i);
+                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
+                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
+
+                                final int N = pkgGrants.size();
+                                for (int z = 0; z < N; z++) {
+                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
+                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
+                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
+
+                                    if (g.granted) {
+                                        serializer.attribute(null, ATTR_GRANTED, "true");
+                                    }
+
+                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
+                                        serializer.attribute(null, ATTR_USER_SET, "true");
+                                    }
+                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
+                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
+                                    }
+                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
+                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
+                                    }
+                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
+                                }
+                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
+                            }
+                        }
+                    }
+                }
+
                 serializer.endDocument();
                 destination.finishWrite(out);
 
@@ -4725,6 +4898,31 @@
             }
         }
 
+        // Backup/restore support
+
+        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
+                boolean isGranted, int restoredFlagSet, int userId) {
+            // This change will be remembered at write-settings time
+            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
+                    mRestoredUserGrants.get(userId);
+            if (grantsByPackage == null) {
+                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
+                mRestoredUserGrants.put(userId, grantsByPackage);
+            }
+
+            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
+            if (grants == null) {
+                grants = new ArraySet<RestoredPermissionGrant>();
+                grantsByPackage.put(pkgName, grants);
+            }
+
+            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
+                    isGranted, restoredFlagSet);
+            grants.add(grant);
+        }
+
+        // Private internals
+
         private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
                 throws IOException, XmlPullParserException {
             final int outerDepth = parser.getDepth();
@@ -4764,6 +4962,46 @@
                         }
                         parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
                     } break;
+
+                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
+                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
+                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
+                    } break;
+                }
+            }
+        }
+
+        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
+                final String pkgName, final int userId) throws IOException, XmlPullParserException {
+            final int outerDepth = parser.getDepth();
+            int type;
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                    continue;
+                }
+
+                switch (parser.getName()) {
+                    case TAG_PERMISSION_ENTRY: {
+                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
+                        final boolean isGranted = "true".equals(
+                                parser.getAttributeValue(null, ATTR_GRANTED));
+
+                        int permBits = 0;
+                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
+                            permBits |= FLAG_PERMISSION_USER_SET;
+                        }
+                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
+                            permBits |= FLAG_PERMISSION_USER_FIXED;
+                        }
+                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
+                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+                        }
+
+                        if (isGranted || permBits != 0) {
+                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
+                        }
+                    } break;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 3d614a3..3248fe6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -32,6 +32,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.os.Binder;
 import android.os.Bundle;
@@ -43,6 +44,7 @@
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -59,7 +61,6 @@
 import android.system.OsConstants;
 import android.util.AtomicFile;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -75,6 +76,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
+import com.android.server.pm.Installer.StorageFlags;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -107,7 +109,7 @@
  */
 public class UserManagerService extends IUserManager.Stub {
     private static final String LOG_TAG = "UserManagerService";
-    static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
+    static final boolean DBG = true; // DO NOT SUBMIT WITH TRUE
     private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE
 
     private static final String TAG_NAME = "name";
@@ -124,6 +126,8 @@
     private static final String ATTR_USER_VERSION = "version";
     private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId";
     private static final String ATTR_RESTRICTED_PROFILE_PARENT_ID = "restrictedProfileParentId";
+    private static final String ATTR_SEED_ACCOUNT_NAME = "seedAccountName";
+    private static final String ATTR_SEED_ACCOUNT_TYPE = "seedAccountType";
     private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions";
     private static final String TAG_USERS = "users";
     private static final String TAG_USER = "user";
@@ -131,6 +135,7 @@
     private static final String TAG_DEVICE_POLICY_RESTRICTIONS = "device_policy_restrictions";
     private static final String TAG_ENTRY = "entry";
     private static final String TAG_VALUE = "value";
+    private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
     private static final String ATTR_KEY = "key";
     private static final String ATTR_VALUE_TYPE = "type";
     private static final String ATTR_MULTIPLE = "m";
@@ -183,16 +188,35 @@
     private final File mUsersDir;
     private final File mUserListFile;
 
-    @GuardedBy("mUsersLock")
-    private final SparseArray<UserInfo> mUsers = new SparseArray<>();
-
     /**
-     * This collection contains each user's account name if the user chose to set one up
-     * during the initial user creation process.  Keeping this information separate from mUsers
-     * to avoid accidentally leak it.
+     * User-related information that is used for persisting to flash. Only UserInfo is
+     * directly exposed to other system apps.
      */
+    private static class UserData {
+        // Basic user information and properties
+        UserInfo info;
+        // Account name used when there is a strong association between a user and an account
+        String account;
+        // Account information for seeding into a newly created user. This could also be
+        // used for login validation for an existing user, for updating their credentials.
+        // In the latter case, data may not need to be persisted as it is only valid for the
+        // current login session.
+        String seedAccountName;
+        String seedAccountType;
+        PersistableBundle seedAccountOptions;
+        // Whether to perist the seed account information to be available after a boot
+        boolean persistSeedData;
+
+        void clearSeedAccountData() {
+            seedAccountName = null;
+            seedAccountType = null;
+            seedAccountOptions = null;
+            persistSeedData = false;
+        }
+    }
+
     @GuardedBy("mUsersLock")
-    private final SparseArray<String> mUserAccounts = new SparseArray<>();
+    private final SparseArray<UserData> mUsers = new SparseArray<>();
 
     /**
      * User restrictions set via UserManager.  This doesn't include restrictions set by
@@ -276,6 +300,8 @@
     private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
             new ArrayList<>();
 
+    private final LockPatternUtils mLockPatternUtils;
+
     private static UserManagerService sInstance;
 
     public static UserManagerService getInstance() {
@@ -320,6 +346,7 @@
         }
         mLocalService = new LocalService();
         LocalServices.addService(UserManagerInternal.class, mLocalService);
+        mLockPatternUtils = new LockPatternUtils(mContext);
     }
 
     void systemReady() {
@@ -328,7 +355,7 @@
         synchronized (mUsersLock) {
             final int userSize = mUsers.size();
             for (int i = 0; i < userSize; i++) {
-                UserInfo ui = mUsers.valueAt(i);
+                UserInfo ui = mUsers.valueAt(i).info;
                 if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) {
                     partials.add(ui);
                 }
@@ -356,20 +383,25 @@
     public String getUserAccount(int userId) {
         checkManageUserAndAcrossUsersFullPermission("get user account");
         synchronized (mUsersLock) {
-            return mUserAccounts.get(userId);
+            return mUsers.get(userId).account;
         }
     }
 
     @Override
     public void setUserAccount(int userId, String accountName) {
         checkManageUserAndAcrossUsersFullPermission("set user account");
-        UserInfo userToUpdate = null;
+        UserData userToUpdate = null;
         synchronized (mPackagesLock) {
             synchronized (mUsersLock) {
-                String currentAccount = mUserAccounts.get(userId);
+                final UserData userData = mUsers.get(userId);
+                if (userData == null) {
+                    Slog.e(LOG_TAG, "User not found for setting user account: u" + userId);
+                    return;
+                }
+                String currentAccount = userData.account;
                 if (!Objects.equal(currentAccount, accountName)) {
-                    mUserAccounts.put(userId, accountName);
-                    userToUpdate = mUsers.get(userId);
+                    userData.account = accountName;
+                    userToUpdate = userData;
                 }
             }
 
@@ -385,7 +417,7 @@
         synchronized (mUsersLock) {
             final int userSize = mUsers.size();
             for (int i = 0; i < userSize; i++) {
-                UserInfo ui = mUsers.valueAt(i);
+                UserInfo ui = mUsers.valueAt(i).info;
                 if (ui.isPrimary() && !mRemovingUserIds.get(ui.id)) {
                     return ui;
                 }
@@ -401,7 +433,7 @@
             ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
             final int userSize = mUsers.size();
             for (int i = 0; i < userSize; i++) {
-                UserInfo ui = mUsers.valueAt(i);
+                UserInfo ui = mUsers.valueAt(i).info;
                 if (ui.partial) {
                     continue;
                 }
@@ -438,7 +470,7 @@
         }
         final int userSize = mUsers.size();
         for (int i = 0; i < userSize; i++) {
-            UserInfo profile = mUsers.valueAt(i);
+            UserInfo profile = mUsers.valueAt(i).info;
             if (!isProfileOf(user, profile)) {
                 continue;
             }
@@ -456,7 +488,7 @@
     @Override
     public int getCredentialOwnerProfile(int userHandle) {
         checkManageUsersPermission("get the credential owner");
-        if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
             synchronized (mUsersLock) {
                 UserInfo profileParent = getProfileParentLU(userHandle);
                 if (profileParent != null) {
@@ -554,7 +586,7 @@
             }
             if (profile.isQuietModeEnabled() != enableQuietMode) {
                 profile.flags ^= UserInfo.FLAG_QUIET_MODE;
-                writeUserLP(profile);
+                writeUserLP(getUserDataLU(profile.id));
                 changed = true;
             }
         }
@@ -590,7 +622,7 @@
             }
             if (info != null && !info.isEnabled()) {
                 info.flags ^= UserInfo.FLAG_DISABLED;
-                writeUserLP(info);
+                writeUserLP(getUserDataLU(info.id));
             }
         }
     }
@@ -630,13 +662,22 @@
      * Should be locked on mUsers before calling this.
      */
     private UserInfo getUserInfoLU(int userId) {
-        UserInfo ui = mUsers.get(userId);
+        final UserData userData = mUsers.get(userId);
         // If it is partial and not in the process of being removed, return as unknown user.
-        if (ui != null && ui.partial && !mRemovingUserIds.get(userId)) {
+        if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
             Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId);
             return null;
         }
-        return ui;
+        return userData != null ? userData.info : null;
+    }
+
+    private UserData getUserDataLU(int userId) {
+        final UserData userData = mUsers.get(userId);
+        // If it is partial and not in the process of being removed, return as unknown user.
+        if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
+            return null;
+        }
+        return userData;
     }
 
     /**
@@ -645,6 +686,17 @@
      */
     private UserInfo getUserInfoNoChecks(int userId) {
         synchronized (mUsersLock) {
+            final UserData userData = mUsers.get(userId);
+            return userData != null ? userData.info : null;
+        }
+    }
+
+    /**
+     * Obtains {@link #mUsersLock} and return UserData from mUsers.
+     * <p>No permissions checking or any addition checks are made</p>
+     */
+    private UserData getUserDataNoChecks(int userId) {
+        synchronized (mUsersLock) {
             return mUsers.get(userId);
         }
     }
@@ -659,14 +711,14 @@
         checkManageUsersPermission("rename users");
         boolean changed = false;
         synchronized (mPackagesLock) {
-            UserInfo info = getUserInfoNoChecks(userId);
-            if (info == null || info.partial) {
+            UserData userData = getUserDataNoChecks(userId);
+            if (userData == null || userData.info.partial) {
                 Slog.w(LOG_TAG, "setUserName: unknown user #" + userId);
                 return;
             }
-            if (name != null && !name.equals(info.name)) {
-                info.name = name;
-                writeUserLP(info);
+            if (name != null && !name.equals(userData.info.name)) {
+                userData.info.name = name;
+                writeUserLP(userData);
                 changed = true;
             }
         }
@@ -681,13 +733,13 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mPackagesLock) {
-                UserInfo info = getUserInfoNoChecks(userId);
-                if (info == null || info.partial) {
+                UserData userData = getUserDataNoChecks(userId);
+                if (userData == null || userData.info.partial) {
                     Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
                     return;
                 }
-                writeBitmapLP(info, bitmap);
-                writeUserLP(info);
+                writeBitmapLP(userData.info, bitmap);
+                writeUserLP(userData);
             }
             sendUserInfoChangedBroadcast(userId);
         } finally {
@@ -734,20 +786,20 @@
     public void makeInitialized(int userId) {
         checkManageUsersPermission("makeInitialized");
         boolean scheduleWriteUser = false;
-        UserInfo info;
+        UserData userData;
         synchronized (mUsersLock) {
-            info = mUsers.get(userId);
-            if (info == null || info.partial) {
+            userData = mUsers.get(userId);
+            if (userData == null || userData.info.partial) {
                 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId);
                 return;
             }
-            if ((info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
-                info.flags |= UserInfo.FLAG_INITIALIZED;
+            if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
+                userData.info.flags |= UserInfo.FLAG_INITIALIZED;
                 scheduleWriteUser = true;
             }
         }
         if (scheduleWriteUser) {
-            scheduleWriteUser(info);
+            scheduleWriteUser(userData);
         }
     }
 
@@ -823,7 +875,7 @@
                 writeUserListLP();
             }
             if (localChanged) {
-                writeUserLP(getUserInfoNoChecks(userId));
+                writeUserLP(getUserDataNoChecks(userId));
             }
         }
 
@@ -938,7 +990,7 @@
 
             if (!UserRestrictionsUtils.areEqual(prevBaseRestrictions, newRestrictions)) {
                 mBaseUserRestrictions.put(userId, newRestrictions);
-                scheduleWriteUser(getUserInfoNoChecks(userId));
+                scheduleWriteUser(getUserDataNoChecks(userId));
             }
         }
 
@@ -1086,7 +1138,7 @@
         final int totalUserCount = mUsers.size();
         // Skip over users being removed
         for (int i = 0; i < totalUserCount; i++) {
-            UserInfo user = mUsers.valueAt(i);
+            UserInfo user = mUsers.valueAt(i).info;
             if (!mRemovingUserIds.get(user.id)
                     && !user.isGuest() && !user.partial) {
                 aliveUserCount++;
@@ -1204,7 +1256,7 @@
             int type;
             while ((type = parser.next()) != XmlPullParser.START_TAG
                     && type != XmlPullParser.END_DOCUMENT) {
-                ;
+                // Skip
             }
 
             if (type != XmlPullParser.START_TAG) {
@@ -1232,16 +1284,15 @@
                     final String name = parser.getName();
                     if (name.equals(TAG_USER)) {
                         String id = parser.getAttributeValue(null, ATTR_ID);
-                        Pair<UserInfo, String> userPair = readUserLP(Integer.parseInt(id));
 
-                        if (userPair != null) {
-                            UserInfo user = userPair.first;
-                            String account = userPair.second;
+                        UserData userData = readUserLP(Integer.parseInt(id));
+
+                        if (userData != null) {
                             synchronized (mUsersLock) {
-                                mUsers.put(user.id, user);
-                                mUserAccounts.put(user.id, account);
-                                if (mNextSerialNumber < 0 || mNextSerialNumber <= user.id) {
-                                    mNextSerialNumber = user.id + 1;
+                                mUsers.put(userData.info.id, userData);
+                                if (mNextSerialNumber < 0
+                                        || mNextSerialNumber <= userData.info.id) {
+                                    mNextSerialNumber = userData.info.id + 1;
                                 }
                             }
                         }
@@ -1285,20 +1336,21 @@
         int userVersion = mUserVersion;
         if (userVersion < 1) {
             // Assign a proper name for the owner, if not initialized correctly before
-            UserInfo user = getUserInfoNoChecks(UserHandle.USER_SYSTEM);
-            if ("Primary".equals(user.name)) {
-                user.name = mContext.getResources().getString(com.android.internal.R.string.owner_name);
-                scheduleWriteUser(user);
+            UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
+            if ("Primary".equals(userData.info.name)) {
+                userData.info.name =
+                        mContext.getResources().getString(com.android.internal.R.string.owner_name);
+                scheduleWriteUser(userData);
             }
             userVersion = 1;
         }
 
         if (userVersion < 2) {
             // Owner should be marked as initialized
-            UserInfo user = getUserInfoNoChecks(UserHandle.USER_SYSTEM);
-            if ((user.flags & UserInfo.FLAG_INITIALIZED) == 0) {
-                user.flags |= UserInfo.FLAG_INITIALIZED;
-                scheduleWriteUser(user);
+            UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
+            if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
+                userData.info.flags |= UserInfo.FLAG_INITIALIZED;
+                scheduleWriteUser(userData);
             }
             userVersion = 2;
         }
@@ -1317,12 +1369,13 @@
             final boolean splitSystemUser = UserManager.isSplitSystemUser();
             synchronized (mUsersLock) {
                 for (int i = 0; i < mUsers.size(); i++) {
-                    UserInfo user = mUsers.valueAt(i);
+                    UserData userData = mUsers.valueAt(i);
                     // In non-split mode, only user 0 can have restricted profiles
-                    if (!splitSystemUser && user.isRestricted()
-                            && (user.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID)) {
-                        user.restrictedProfileParentId = UserHandle.USER_SYSTEM;
-                        scheduleWriteUser(user);
+                    if (!splitSystemUser && userData.info.isRestricted()
+                            && (userData.info.restrictedProfileParentId
+                                    == UserInfo.NO_PROFILE_GROUP_ID)) {
+                        userData.info.restrictedProfileParentId = UserHandle.USER_SYSTEM;
+                        scheduleWriteUser(userData);
                     }
                 }
             }
@@ -1352,8 +1405,10 @@
         UserInfo system = new UserInfo(UserHandle.USER_SYSTEM,
                 mContext.getResources().getString(com.android.internal.R.string.owner_name), null,
                 flags);
+        UserData userData = new UserData();
+        userData.info = system;
         synchronized (mUsersLock) {
-            mUsers.put(system.id, system);
+            mUsers.put(system.id, userData);
         }
         mNextSerialNumber = MIN_USER_ID;
         mUserVersion = USER_VERSION;
@@ -1367,17 +1422,17 @@
         initDefaultGuestRestrictions();
 
         writeUserListLP();
-        writeUserLP(system);
+        writeUserLP(userData);
     }
 
-    private void scheduleWriteUser(UserInfo userInfo) {
+    private void scheduleWriteUser(UserData UserData) {
         if (DBG) {
             debug("scheduleWriteUser");
         }
         // No need to wrap it within a lock -- worst case, we'll just post the same message
         // twice.
-        if (!mHandler.hasMessages(WRITE_USER_MSG, userInfo)) {
-            Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userInfo);
+        if (!mHandler.hasMessages(WRITE_USER_MSG, UserData)) {
+            Message msg = mHandler.obtainMessage(WRITE_USER_MSG, UserData);
             mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY);
         }
     }
@@ -1389,12 +1444,12 @@
      *   <name>Primary</name>
      * </user>
      */
-    private void writeUserLP(UserInfo userInfo) {
+    private void writeUserLP(UserData userData) {
         if (DBG) {
-            debug("writeUserLP " + userInfo);
+            debug("writeUserLP " + userData);
         }
         FileOutputStream fos = null;
-        AtomicFile userFile = new AtomicFile(new File(mUsersDir, userInfo.id + XML_SUFFIX));
+        AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX));
         try {
             fos = userFile.startWrite();
             final BufferedOutputStream bos = new BufferedOutputStream(fos);
@@ -1405,6 +1460,7 @@
             serializer.startDocument(null, true);
             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
 
+            final UserInfo userInfo = userData.info;
             serializer.startTag(null, TAG_USER);
             serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id));
             serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber));
@@ -1429,6 +1485,15 @@
                 serializer.attribute(null, ATTR_RESTRICTED_PROFILE_PARENT_ID,
                         Integer.toString(userInfo.restrictedProfileParentId));
             }
+            // Write seed data
+            if (userData.persistSeedData) {
+                if (userData.seedAccountName != null) {
+                    serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName);
+                }
+                if (userData.seedAccountType != null) {
+                    serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType);
+                }
+            }
             serializer.startTag(null, TAG_NAME);
             serializer.text(userInfo.name);
             serializer.endTag(null, TAG_NAME);
@@ -1439,23 +1504,24 @@
                         mDevicePolicyLocalUserRestrictions.get(userInfo.id),
                         TAG_DEVICE_POLICY_RESTRICTIONS);
             }
-            // Update the account field if it is set.
-            String account;
-            synchronized (mUsersLock) {
-                account = mUserAccounts.get(userInfo.id);
-            }
-            if (account != null) {
+
+            if (userData.account != null) {
                 serializer.startTag(null, TAG_ACCOUNT);
-                serializer.text(account);
+                serializer.text(userData.account);
                 serializer.endTag(null, TAG_ACCOUNT);
             }
 
+            if (userData.persistSeedData && userData.seedAccountOptions != null) {
+                serializer.startTag(null, TAG_SEED_ACCOUNT_OPTIONS);
+                userData.seedAccountOptions.saveToXml(serializer);
+                serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS);
+            }
             serializer.endTag(null, TAG_USER);
 
             serializer.endDocument();
             userFile.finishWrite(fos);
         } catch (Exception ioe) {
-            Slog.e(LOG_TAG, "Error writing user info " + userInfo.id + "\n" + ioe);
+            Slog.e(LOG_TAG, "Error writing user info " + userData.info.id + "\n" + ioe);
             userFile.failWrite(fos);
         }
     }
@@ -1502,7 +1568,7 @@
             synchronized (mUsersLock) {
                 userIdsToWrite = new int[mUsers.size()];
                 for (int i = 0; i < userIdsToWrite.length; i++) {
-                    UserInfo user = mUsers.valueAt(i);
+                    UserInfo user = mUsers.valueAt(i).info;
                     userIdsToWrite[i] = user.id;
                 }
             }
@@ -1522,7 +1588,7 @@
         }
     }
 
-    private Pair<UserInfo, String> readUserLP(int id) {
+    private UserData readUserLP(int id) {
         int flags = 0;
         int serialNumber = id;
         String name = null;
@@ -1534,6 +1600,10 @@
         int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
         boolean partial = false;
         boolean guestToRemove = false;
+        boolean persistSeedData = false;
+        String seedAccountName = null;
+        String seedAccountType = null;
+        PersistableBundle seedAccountOptions = null;
         Bundle baseRestrictions = new Bundle();
         Bundle localRestrictions = new Bundle();
 
@@ -1547,7 +1617,7 @@
             int type;
             while ((type = parser.next()) != XmlPullParser.START_TAG
                     && type != XmlPullParser.END_DOCUMENT) {
-                ;
+                // Skip
             }
 
             if (type != XmlPullParser.START_TAG) {
@@ -1579,6 +1649,12 @@
                     guestToRemove = true;
                 }
 
+                seedAccountName = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_NAME);
+                seedAccountType = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_TYPE);
+                if (seedAccountName != null || seedAccountType != null) {
+                    persistSeedData = true;
+                }
+
                 int outerDepth = parser.getDepth();
                 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                        && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -1600,10 +1676,14 @@
                         if (type == XmlPullParser.TEXT) {
                             account = parser.getText();
                         }
+                    } else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) {
+                        seedAccountOptions = PersistableBundle.restoreFromXml(parser);
+                        persistSeedData = true;
                     }
                 }
             }
 
+            // Create the UserInfo object that gets passed around
             UserInfo userInfo = new UserInfo(id, name, iconPath, flags);
             userInfo.serialNumber = serialNumber;
             userInfo.creationTime = creationTime;
@@ -1612,12 +1692,21 @@
             userInfo.guestToRemove = guestToRemove;
             userInfo.profileGroupId = profileGroupId;
             userInfo.restrictedProfileParentId = restrictedProfileParentId;
+
+            // Create the UserData object that's internal to this class
+            UserData userData = new UserData();
+            userData.info = userInfo;
+            userData.account = account;
+            userData.seedAccountName = seedAccountName;
+            userData.seedAccountType = seedAccountType;
+            userData.persistSeedData = persistSeedData;
+            userData.seedAccountOptions = seedAccountOptions;
+
             synchronized (mRestrictionsLock) {
                 mBaseUserRestrictions.put(id, baseRestrictions);
                 mDevicePolicyLocalUserRestrictions.put(id, localRestrictions);
             }
-            return new Pair<>(userInfo, account);
-
+            return userData;
         } catch (IOException ioe) {
         } catch (XmlPullParserException pe) {
         } finally {
@@ -1662,26 +1751,6 @@
     }
 
     /**
-     * Removes all the restrictions files (res_<packagename>) for a given user.
-     * Does not do any permissions checking.
-     */
-    private void cleanAppRestrictions(int userId) {
-        synchronized (mPackagesLock) {
-            File dir = Environment.getUserSystemDirectory(userId);
-            String[] files = dir.list();
-            if (files == null) return;
-            for (String fileName : files) {
-                if (fileName.startsWith(RESTRICTIONS_FILE_PREFIX)) {
-                    File resFile = new File(dir, fileName);
-                    if (resFile.exists()) {
-                        resFile.delete();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Removes the app restrictions file for a specific package and user id, if it exists.
      */
     private void cleanAppRestrictionsForPackage(String pkg, int userId) {
@@ -1719,13 +1788,14 @@
         final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
         final long ident = Binder.clearCallingIdentity();
         UserInfo userInfo;
+        UserData userData;
         final int userId;
         try {
             synchronized (mPackagesLock) {
-                UserInfo parent = null;
+                UserData parent = null;
                 if (parentId != UserHandle.USER_NULL) {
                     synchronized (mUsersLock) {
-                        parent = getUserInfoLU(parentId);
+                        parent = getUserDataLU(parentId);
                     }
                     if (parent == null) return null;
                 }
@@ -1754,7 +1824,7 @@
                                 + "specified");
                         return null;
                     }
-                    if (!parent.canHaveProfile()) {
+                    if (!parent.info.canHaveProfile()) {
                         Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
                                 + "created for the specified parent user id " + parentId);
                         return null;
@@ -1772,7 +1842,11 @@
                     }
                 }
 
-                if (parent != null && parent.isEphemeral()) {
+                // Add ephemeral flag to guests if required. Also inherit it from parent.
+                boolean ephemeralGuests = Resources.getSystem()
+                        .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
+                if ((isGuest && ephemeralGuests)
+                        || (parent != null && parent.info.isEphemeral())) {
                     flags |= UserInfo.FLAG_EPHEMERAL;
                 }
                 userId = getNextAvailableId();
@@ -1781,24 +1855,26 @@
                 long now = System.currentTimeMillis();
                 userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
                 userInfo.partial = true;
+                userData = new UserData();
+                userData.info = userInfo;
                 Environment.getUserSystemDirectory(userInfo.id).mkdirs();
                 synchronized (mUsersLock) {
-                    mUsers.put(userId, userInfo);
+                    mUsers.put(userId, userData);
                 }
                 writeUserListLP();
                 if (parent != null) {
                     if (isManagedProfile) {
-                        if (parent.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
-                            parent.profileGroupId = parent.id;
+                        if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
+                            parent.info.profileGroupId = parent.info.id;
                             writeUserLP(parent);
                         }
-                        userInfo.profileGroupId = parent.profileGroupId;
+                        userInfo.profileGroupId = parent.info.profileGroupId;
                     } else if (isRestricted) {
-                        if (parent.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
-                            parent.restrictedProfileParentId = parent.id;
+                        if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
+                            parent.info.restrictedProfileParentId = parent.info.id;
                             writeUserLP(parent);
                         }
-                        userInfo.restrictedProfileParentId = parent.restrictedProfileParentId;
+                        userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId;
                     }
                 }
             }
@@ -1818,7 +1894,7 @@
             mPm.createNewUser(userId);
             userInfo.partial = false;
             synchronized (mPackagesLock) {
-                writeUserLP(userInfo);
+                writeUserLP(userData);
             }
             updateUserIds();
             Bundle restrictions = new Bundle();
@@ -1845,6 +1921,7 @@
     /**
      * @hide
      */
+    @Override
     public UserInfo createRestrictedProfile(String name, int parentUserId) {
         checkManageUsersPermission("setupRestrictedProfile");
         final UserInfo user = createProfileForUser(name, UserInfo.FLAG_RESTRICTED, parentUserId);
@@ -1869,7 +1946,7 @@
         synchronized (mUsersLock) {
             final int size = mUsers.size();
             for (int i = 0; i < size; i++) {
-                final UserInfo user = mUsers.valueAt(i);
+                final UserInfo user = mUsers.valueAt(i).info;
                 if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) {
                     return user;
                 }
@@ -1884,6 +1961,7 @@
      * @param userHandle the userid of the current guest
      * @return whether the user could be marked for deletion
      */
+    @Override
     public boolean markGuestForDeletion(int userHandle) {
         checkManageUsersPermission("Only the system can remove users");
         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
@@ -1894,15 +1972,15 @@
 
         long ident = Binder.clearCallingIdentity();
         try {
-            final UserInfo user;
+            final UserData userData;
             synchronized (mPackagesLock) {
                 synchronized (mUsersLock) {
-                    user = mUsers.get(userHandle);
-                    if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
+                    userData = mUsers.get(userHandle);
+                    if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
                         return false;
                     }
                 }
-                if (!user.isGuest()) {
+                if (!userData.info.isGuest()) {
                     return false;
                 }
                 // We set this to a guest user that is to be removed. This is a temporary state
@@ -1910,11 +1988,11 @@
                 // removed. This user will still show up in getUserInfo() calls.
                 // If we don't get around to removing this Guest user, it will be purged on next
                 // startup.
-                user.guestToRemove = true;
+                userData.info.guestToRemove = true;
                 // Mark it as disabled, so that it isn't returned any more when
                 // profiles are queried.
-                user.flags |= UserInfo.FLAG_DISABLED;
-                writeUserLP(user);
+                userData.info.flags |= UserInfo.FLAG_DISABLED;
+                writeUserLP(userData);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -1927,6 +2005,7 @@
      * after the user's processes have been terminated.
      * @param userHandle the user's id
      */
+    @Override
     public boolean removeUser(int userHandle) {
         checkManageUsersPermission("Only the system can remove users");
         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
@@ -1937,7 +2016,7 @@
 
         long ident = Binder.clearCallingIdentity();
         try {
-            final UserInfo user;
+            final UserData userData;
             int currentUser = ActivityManager.getCurrentUser();
             if (currentUser == userHandle) {
                 Log.w(LOG_TAG, "Current user cannot be removed");
@@ -1945,8 +2024,8 @@
             }
             synchronized (mPackagesLock) {
                 synchronized (mUsersLock) {
-                    user = mUsers.get(userHandle);
-                    if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
+                    userData = mUsers.get(userHandle);
+                    if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
                         return false;
                     }
 
@@ -1964,18 +2043,18 @@
                 // Set this to a partially created user, so that the user will be purged
                 // on next startup, in case the runtime stops now before stopping and
                 // removing the user completely.
-                user.partial = true;
+                userData.info.partial = true;
                 // Mark it as disabled, so that it isn't returned any more when
                 // profiles are queried.
-                user.flags |= UserInfo.FLAG_DISABLED;
-                writeUserLP(user);
+                userData.info.flags |= UserInfo.FLAG_DISABLED;
+                writeUserLP(userData);
             }
 
-            if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
-                    && user.isManagedProfile()) {
+            if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
+                    && userData.info.isManagedProfile()) {
                 // Send broadcast to notify system that the user removed was a
                 // managed user.
-                sendProfileRemovedBroadcast(user.profileGroupId, user.id);
+                sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);
             }
 
             if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
@@ -2020,6 +2099,7 @@
                                         + userHandle);
                             }
                             new Thread() {
+                                @Override
                                 public void run() {
                                     // Clean up any ActivityManager state
                                     LocalServices.getService(ActivityManagerInternal.class)
@@ -2044,7 +2124,6 @@
         // Remove this user from the list
         synchronized (mUsersLock) {
             mUsers.remove(userHandle);
-            mUserAccounts.delete(userHandle);
             mIsUserManaged.delete(userHandle);
         }
         synchronized (mRestrictionsLock) {
@@ -2061,7 +2140,13 @@
             writeUserListLP();
         }
         updateUserIds();
-        removeDirectoryRecursive(Environment.getUserSystemDirectory(userHandle));
+        File userDir = Environment.getUserSystemDirectory(userHandle);
+        File renamedUserDir = Environment.getUserSystemDirectory(UserHandle.USER_NULL - userHandle);
+        if (userDir.renameTo(renamedUserDir)) {
+            removeDirectoryRecursive(renamedUserDir);
+        } else {
+            removeDirectoryRecursive(userDir);
+        }
     }
 
     private void removeDirectoryRecursive(File parent) {
@@ -2123,29 +2208,6 @@
         }
     }
 
-    private void unhideAllInstalledAppsForUser(final int userHandle) {
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                List<ApplicationInfo> apps =
-                        mPm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES,
-                                userHandle).getList();
-                final long ident = Binder.clearCallingIdentity();
-                try {
-                    for (ApplicationInfo appInfo : apps) {
-                        if ((appInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0
-                                && (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HIDDEN)
-                                        != 0) {
-                            mPm.setApplicationHiddenSettingAsUser(appInfo.packageName, false,
-                                    userHandle);
-                        }
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
-            }
-        });
-    }
     private int getUidForPackage(String packageName) {
         long ident = Binder.clearCallingIdentity();
         try {
@@ -2375,14 +2437,14 @@
         synchronized (mUsersLock) {
             final int userSize = mUsers.size();
             for (int i = 0; i < userSize; i++) {
-                if (!mUsers.valueAt(i).partial) {
+                if (!mUsers.valueAt(i).info.partial) {
                     num++;
                 }
             }
             final int[] newUsers = new int[num];
             int n = 0;
             for (int i = 0; i < userSize; i++) {
-                if (!mUsers.valueAt(i).partial) {
+                if (!mUsers.valueAt(i).info.partial) {
                     newUsers[n++] = mUsers.keyAt(i);
                 }
             }
@@ -2391,28 +2453,41 @@
     }
 
     /**
-     * Called right before a user starts.  This will not be called for the system user.
+     * Called right before a user is started. This gives us a chance to prepare
+     * app storage and apply any user restrictions.
      */
     public void onBeforeStartUser(int userId) {
-        synchronized (mRestrictionsLock) {
-            applyUserRestrictionsLR(userId);
+        mPm.reconcileAppsData(userId, Installer.FLAG_DE_STORAGE);
+
+        if (userId != UserHandle.USER_SYSTEM) {
+            synchronized (mRestrictionsLock) {
+                applyUserRestrictionsLR(userId);
+            }
         }
     }
 
     /**
+     * Called right before a user is unlocked. This gives us a chance to prepare
+     * app storage.
+     */
+    public void onBeforeUnlockUser(int userId) {
+        mPm.reconcileAppsData(userId, Installer.FLAG_CE_STORAGE);
+    }
+
+    /**
      * Make a note of the last started time of a user and do some cleanup.
      * @param userId the user that was just foregrounded
      */
     public void onUserForeground(int userId) {
-        UserInfo user = getUserInfoNoChecks(userId);
-        if (user == null || user.partial) {
+        UserData userData = getUserDataNoChecks(userId);
+        if (userData == null || userData.info.partial) {
             Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
             return;
         }
         long now = System.currentTimeMillis();
         if (now > EPOCH_PLUS_30_YEARS) {
-            user.lastLoggedInTime = now;
-            scheduleWriteUser(user);
+            userData.info.lastLoggedInTime = now;
+            scheduleWriteUser(userData);
         }
     }
 
@@ -2504,6 +2579,91 @@
     }
 
     @Override
+    public void setSeedAccountData(int userId, String accountName, String accountType,
+            PersistableBundle accountOptions, boolean persist) {
+        checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data");
+        synchronized (mPackagesLock) {
+            final UserData userData;
+            synchronized (mUsersLock) {
+                userData = getUserDataLU(userId);
+                if (userData == null) {
+                    Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId);
+                    return;
+                }
+                userData.seedAccountName = accountName;
+                userData.seedAccountType = accountType;
+                userData.seedAccountOptions = accountOptions;
+                userData.persistSeedData = persist;
+            }
+            if (persist) {
+                writeUserLP(userData);
+            }
+        }
+    }
+
+    @Override
+    public String getSeedAccountName() throws RemoteException {
+        checkManageUsersPermission("Cannot get seed account information");
+        synchronized (mUsersLock) {
+            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
+            return userData.seedAccountName;
+        }
+    }
+
+    @Override
+    public String getSeedAccountType() throws RemoteException {
+        checkManageUsersPermission("Cannot get seed account information");
+        synchronized (mUsersLock) {
+            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
+            return userData.seedAccountType;
+        }
+    }
+
+    @Override
+    public PersistableBundle getSeedAccountOptions() throws RemoteException {
+        checkManageUsersPermission("Cannot get seed account information");
+        synchronized (mUsersLock) {
+            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
+            return userData.seedAccountOptions;
+        }
+    }
+
+    @Override
+    public void clearSeedAccountData() throws RemoteException {
+        checkManageUsersPermission("Cannot clear seed account information");
+        synchronized (mPackagesLock) {
+            UserData userData;
+            synchronized (mUsersLock) {
+                userData = getUserDataLU(UserHandle.getCallingUserId());
+                if (userData == null) return;
+                userData.clearSeedAccountData();
+            }
+            writeUserLP(userData);
+        }
+    }
+
+    @Override
+    public boolean someUserHasSeedAccount(String accountName, String accountType)
+            throws RemoteException {
+        checkManageUsersPermission("Cannot check seed account information");
+        synchronized (mUsersLock) {
+            final int userSize = mUsers.size();
+            for (int i = 0; i < userSize; i++) {
+                final UserData data = mUsers.valueAt(i);
+                if (data.info.isInitialized()) continue;
+                if (data.seedAccountName == null || !data.seedAccountName.equals(accountName)) {
+                    continue;
+                }
+                if (data.seedAccountType == null || !data.seedAccountType.equals(accountType)) {
+                    continue;
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
     public void onShellCommand(FileDescriptor in, FileDescriptor out,
             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
         (new Shell()).exec(this, in, out, err, args, resultReceiver);
@@ -2560,35 +2720,36 @@
             synchronized (mUsersLock) {
                 pw.println("Users:");
                 for (int i = 0; i < mUsers.size(); i++) {
-                    UserInfo user = mUsers.valueAt(i);
-                    if (user == null) {
+                    UserData userData = mUsers.valueAt(i);
+                    if (userData == null) {
                         continue;
                     }
-                    final int userId = user.id;
-                    pw.print("  "); pw.print(user);
-                    pw.print(" serialNo="); pw.print(user.serialNumber);
+                    UserInfo userInfo = userData.info;
+                    final int userId = userInfo.id;
+                    pw.print("  "); pw.print(userInfo);
+                    pw.print(" serialNo="); pw.print(userInfo.serialNumber);
                     if (mRemovingUserIds.get(userId)) {
                         pw.print(" <removing> ");
                     }
-                    if (user.partial) {
+                    if (userInfo.partial) {
                         pw.print(" <partial>");
                     }
                     pw.println();
                     pw.print("    Created: ");
-                    if (user.creationTime == 0) {
+                    if (userInfo.creationTime == 0) {
                         pw.println("<unknown>");
                     } else {
                         sb.setLength(0);
-                        TimeUtils.formatDuration(now - user.creationTime, sb);
+                        TimeUtils.formatDuration(now - userInfo.creationTime, sb);
                         sb.append(" ago");
                         pw.println(sb);
                     }
                     pw.print("    Last logged in: ");
-                    if (user.lastLoggedInTime == 0) {
+                    if (userInfo.lastLoggedInTime == 0) {
                         pw.println("<unknown>");
                     } else {
                         sb.setLength(0);
-                        TimeUtils.formatDuration(now - user.lastLoggedInTime, sb);
+                        TimeUtils.formatDuration(now - userInfo.lastLoggedInTime, sb);
                         sb.append(" ago");
                         pw.println(sb);
                     }
@@ -2597,22 +2758,35 @@
                     pw.println("    Restrictions:");
                     synchronized (mRestrictionsLock) {
                         UserRestrictionsUtils.dumpRestrictions(
-                                pw, "      ", mBaseUserRestrictions.get(user.id));
+                                pw, "      ", mBaseUserRestrictions.get(userInfo.id));
                         pw.println("    Device policy local restrictions:");
                         UserRestrictionsUtils.dumpRestrictions(
-                                pw, "      ", mDevicePolicyLocalUserRestrictions.get(user.id));
+                                pw, "      ", mDevicePolicyLocalUserRestrictions.get(userInfo.id));
                         pw.println("    Effective restrictions:");
                         UserRestrictionsUtils.dumpRestrictions(
-                                pw, "      ", mCachedEffectiveUserRestrictions.get(user.id));
+                                pw, "      ", mCachedEffectiveUserRestrictions.get(userInfo.id));
                     }
-                    pw.println();
-                    String accountName = mUserAccounts.get(userId);
-                    if (accountName != null) {
-                        pw.print("    Account name: " + accountName);
+
+                    if (userData.account != null) {
+                        pw.print("    Account name: " + userData.account);
                         pw.println();
                     }
+
+                    if (userData.seedAccountName != null) {
+                        pw.print("    Seed account name: " + userData.seedAccountName);
+                        pw.println();
+                        if (userData.seedAccountType != null) {
+                            pw.print("         account type: " + userData.seedAccountType);
+                            pw.println();
+                        }
+                        if (userData.seedAccountOptions != null) {
+                            pw.print("         account options exist");
+                            pw.println();
+                        }
+                    }
                 }
             }
+            pw.println();
             pw.println("  Device policy global restrictions:");
             synchronized (mRestrictionsLock) {
                 UserRestrictionsUtils
@@ -2627,6 +2801,12 @@
                 pw.println();
                 pw.println("  Device managed: " + mIsDeviceManaged);
             }
+            // Dump some capabilities
+            pw.println();
+            pw.println("  Max users: " + UserManager.getMaxSupportedUsers());
+            pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
+            pw.println("  All guests ephemeral: " + Resources.getSystem().getBoolean(
+                    com.android.internal.R.bool.config_guestUserEphemeral));
         }
     }
 
@@ -2638,10 +2818,10 @@
                 case WRITE_USER_MSG:
                     removeMessages(WRITE_USER_MSG, msg.obj);
                     synchronized (mPackagesLock) {
-                        int userId = ((UserInfo) msg.obj).id;
-                        UserInfo userInfo = getUserInfoNoChecks(userId);
-                        if (userInfo != null) {
-                            writeUserLP(userInfo);
+                        int userId = ((UserData) msg.obj).info.id;
+                        UserData userData = getUserDataNoChecks(userId);
+                        if (userData != null) {
+                            writeUserLP(userData);
                         }
                     }
             }
@@ -2679,10 +2859,10 @@
                 invalidateEffectiveUserRestrictionsLR(userId);
             }
 
-            final UserInfo userInfo = getUserInfoNoChecks(userId);
+            final UserData userData = getUserDataNoChecks(userId);
             synchronized (mPackagesLock) {
-                if (userInfo != null) {
-                    writeUserLP(userInfo);
+                if (userData != null) {
+                    writeUserLP(userData);
                 } else {
                     Slog.w(LOG_TAG, "UserInfo not found for " + userId);
                 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 75910a7..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;
@@ -183,10 +186,15 @@
     static final int LONG_PRESS_HOME_NOTHING = 0;
     static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 1;
     static final int LONG_PRESS_HOME_ASSIST = 2;
+    static final int LONG_PRESS_HOME_PICTURE_IN_PICTURE = 3;
+    static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_PICTURE_IN_PICTURE;
 
     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;
 
@@ -407,6 +415,7 @@
     int mDoublePressOnPowerBehavior;
     int mTriplePressOnPowerBehavior;
     int mShortPressOnSleepBehavior;
+    int mShortPressWindowBehavior;
     boolean mAwake;
     boolean mScreenOnEarly;
     boolean mScreenOnFully;
@@ -1313,16 +1322,26 @@
         }
     }
 
-    private void handleLongPressOnHome(int deviceId) {
-        if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
-            mHomeConsumed = true;
-            performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+    private void handleLongPressOnHome(int deviceId, KeyEvent event) {
+        if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_NOTHING) {
+            return;
+        }
+        mHomeConsumed = true;
+        performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
 
-            if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
+        switch (mLongPressOnHomeBehavior) {
+            case LONG_PRESS_HOME_RECENT_SYSTEM_UI:
                 toggleRecentApps();
-            } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_ASSIST) {
+                break;
+            case LONG_PRESS_HOME_ASSIST:
                 launchAssistAction(null, deviceId);
-            }
+                break;
+            case LONG_PRESS_HOME_PICTURE_IN_PICTURE:
+                handlePipKey(event);
+                break;
+            default:
+                Log.w(TAG, "Not defined home long press behavior: " + mLongPressOnHomeBehavior);
+                break;
         }
     }
 
@@ -1333,6 +1352,13 @@
         }
     }
 
+    private void handlePipKey(KeyEvent event) {
+        if (DEBUG_INPUT) Log.d(TAG, "handlePipKey event=" + event);
+        Intent intent = new Intent(Intent.ACTION_PICTURE_IN_PICTURE_BUTTON);
+        intent.putExtra(Intent.EXTRA_KEY_EVENT, event);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
     private final Runnable mHomeDoubleTapTimeoutRunnable = new Runnable() {
         @Override
         public void run() {
@@ -1625,7 +1651,7 @@
         mLongPressOnHomeBehavior = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_longPressOnHomeBehavior);
         if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
-                mLongPressOnHomeBehavior > LONG_PRESS_HOME_ASSIST) {
+                mLongPressOnHomeBehavior > LAST_LONG_PRESS_HOME_BEHAVIOR) {
             mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
         }
 
@@ -1635,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
@@ -2851,7 +2882,7 @@
                 }
             } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                 if (!keyguardOn) {
-                    handleLongPressOnHome(event.getDeviceId());
+                    handleLongPressOnHome(event.getDeviceId(), event);
                 }
             }
             return -1;
@@ -3003,6 +3034,14 @@
                         UserHandle.CURRENT_OR_SELF);
             }
             return -1;
+        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP
+                || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+                || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
+            if (mUseTvRouting) {
+                // On TVs volume keys never go to the foreground app.
+                dispatchDirectAudioEvent(event);
+                return -1;
+            }
         } else if (KeyEvent.isMetaKey(keyCode)) {
             if (down) {
                 mPendingMetaAction = true;
@@ -4054,7 +4093,13 @@
             cf.top = vf.top = mStableTop;
             cf.right = vf.right = mStableRight;
             vf.bottom = mStableBottom;
-            cf.bottom = mContentBottom;
+
+            if (adjust == SOFT_INPUT_ADJUST_RESIZE) {
+                cf.bottom = mContentBottom;
+            } else {
+                cf.bottom = mDockBottom;
+                vf.bottom = mContentBottom;
+            }
         } else {
 
             // Default policy decor for the default display
@@ -5084,10 +5129,6 @@
             case KeyEvent.KEYCODE_VOLUME_DOWN:
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_MUTE: {
-                if (mUseTvRouting) {
-                    // On TVs volume keys never go to the foreground app
-                    result &= ~ACTION_PASS_TO_USER;
-                }
                 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                     if (down) {
                         if (interactive && !mScreenshotChordVolumeDownKeyTriggered
@@ -5147,19 +5188,17 @@
                             break;
                         }
                     }
-
-                    if ((result & ACTION_PASS_TO_USER) == 0) {
-                        if (mUseTvRouting) {
-                            dispatchDirectAudioEvent(event);
-                        } else {
-                            // If we aren't passing to the user and no one else
-                            // handled it send it to the session manager to
-                            // figure out.
-                            MediaSessionLegacyHelper.getHelper(mContext)
-                                    .sendVolumeKeyEvent(event, true);
-                        }
-                        break;
-                    }
+                }
+                if (mUseTvRouting) {
+                    // On TVs, defer special key handlings to
+                    // {@link interceptKeyBeforeDispatching()}.
+                    result |= ACTION_PASS_TO_USER;
+                } else if ((result & ACTION_PASS_TO_USER) == 0) {
+                    // If we aren't passing to the user and no one else
+                    // handled it send it to the session manager to
+                    // figure out.
+                    MediaSessionLegacyHelper.getHelper(mContext)
+                            .sendVolumeKeyEvent(event, true);
                 }
                 break;
             }
@@ -5302,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;
             }
         }
 
@@ -6275,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/ShortcutManager.java b/services/core/java/com/android/server/policy/ShortcutManager.java
index 9908624..9284442 100644
--- a/services/core/java/com/android/server/policy/ShortcutManager.java
+++ b/services/core/java/com/android/server/policy/ShortcutManager.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
 import com.android.internal.util.XmlUtils;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -47,8 +48,10 @@
     private static final String ATTRIBUTE_CLASS = "class";
     private static final String ATTRIBUTE_SHORTCUT = "shortcut";
     private static final String ATTRIBUTE_CATEGORY = "category";
+    private static final String ATTRIBUTE_SHIFT = "shift";
 
     private final SparseArray<ShortcutInfo> mShortcuts = new SparseArray<>();
+    private final SparseArray<ShortcutInfo> mShiftShortcuts = new SparseArray<>();
 
     private final Context mContext;
     
@@ -75,17 +78,21 @@
     public Intent getIntent(KeyCharacterMap kcm, int keyCode, int metaState) {
         ShortcutInfo shortcut = null;
 
+        // If the Shift key is preesed, then search for the shift shortcuts.
+        boolean isShiftOn = (metaState & KeyEvent.META_SHIFT_ON) == KeyEvent.META_SHIFT_ON;
+        SparseArray<ShortcutInfo> shortcutMap = isShiftOn ? mShiftShortcuts : mShortcuts;
+
         // First try the exact keycode (with modifiers).
         int shortcutChar = kcm.get(keyCode, metaState);
         if (shortcutChar != 0) {
-            shortcut = mShortcuts.get(shortcutChar);
+            shortcut = shortcutMap.get(shortcutChar);
         }
 
         // Next try the primary character on that key.
         if (shortcut == null) {
             shortcutChar = Character.toLowerCase(kcm.getDisplayLabel(keyCode));
             if (shortcutChar != 0) {
-                shortcut = mShortcuts.get(shortcutChar);
+                shortcut = shortcutMap.get(shortcutChar);
             }
         }
 
@@ -114,6 +121,7 @@
                 String className = parser.getAttributeValue(null, ATTRIBUTE_CLASS);
                 String shortcutName = parser.getAttributeValue(null, ATTRIBUTE_SHORTCUT);
                 String categoryName = parser.getAttributeValue(null, ATTRIBUTE_CATEGORY);
+                String shiftName = parser.getAttributeValue(null, ATTRIBUTE_SHIFT);
 
                 if (TextUtils.isEmpty(shortcutName)) {
                     Log.w(TAG, "Unable to get shortcut for: " + packageName + "/" + className);
@@ -121,6 +129,7 @@
                 }
 
                 final int shortcutChar = shortcutName.charAt(0);
+                final boolean isShiftShortcut = (shiftName != null && shiftName.equals("true"));
 
                 final Intent intent;
                 final String title;
@@ -158,7 +167,11 @@
                 }
 
                 ShortcutInfo shortcut = new ShortcutInfo(title, intent);
-                mShortcuts.put(shortcutChar, shortcut);
+                if (isShiftShortcut) {
+                    mShiftShortcuts.put(shortcutChar, shortcut);
+                } else {
+                    mShortcuts.put(shortcutChar, shortcut);
+                }
             }
         } catch (XmlPullParserException e) {
             Log.w(TAG, "Got exception parsing bookmarks.", e);
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/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index d888c56..1d498e1 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -290,14 +290,9 @@
     }
 
     public void setDeviceLockedForUser(int userId, boolean locked) {
-        if (LockPatternUtils.isSeparateWorkChallengeEnabled()) {
-            UserInfo info = mUserManager.getUserInfo(userId);
-            if (info.isManagedProfile()) {
-                synchronized (mDeviceLockedForUser) {
-                    mDeviceLockedForUser.put(userId, locked);
-                }
-            } else {
-                Log.wtf(TAG, "Requested to change lock state for non-profile user " + userId);
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+            synchronized (mDeviceLockedForUser) {
+                mDeviceLockedForUser.put(userId, locked);
             }
         }
     }
@@ -669,24 +664,29 @@
         public boolean isDeviceLocked(int userId) throws RemoteException {
             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                     false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
-            if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
-                userId = resolveProfileParent(userId);
-            }
 
-            return isDeviceLockedInner(userId);
+            long token = Binder.clearCallingIdentity();
+            try {
+                if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+                    userId = resolveProfileParent(userId);
+                }
+                return isDeviceLockedInner(userId);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override
         public boolean isDeviceSecure(int userId) throws RemoteException {
             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                     false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
-            if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
-                userId = resolveProfileParent(userId);
-            }
 
             long token = Binder.clearCallingIdentity();
             try {
-                return new LockPatternUtils(mContext).isSecure(userId);
+                if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+                    userId = resolveProfileParent(userId);
+                }
+                return mLockPatternUtils.isSecure(userId);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -783,6 +783,7 @@
 
         @Override
         public void setDeviceLockedForUser(int userId, boolean value) {
+            enforceReportPermission();
             mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
                     .sendToTarget();
         }
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index a035826..ebbb8b3 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -116,7 +116,7 @@
 
     public void close() {
         synchronized (mLock) {
-            if (mPtr != 0l) {
+            if (mPtr != 0L) {
                 nativeClose(mPtr);
             }
         }
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index d814ebf..3193ff8 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -465,7 +465,7 @@
         try {
             context = mContext.createPackageContextAsUser("android", 0, user);
         } catch (NameNotFoundException e) {
-            Slog.e(TAG, "failed to create package contenxt as user " + user);
+            Slog.e(TAG, "failed to create package context as user " + user);
             context = mContext;
         }
         return context.getContentResolver();
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index a7a4ed1..0622fad 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -39,6 +39,8 @@
 import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -85,9 +87,6 @@
 // made visible or hidden at the next transition.
 public class AppTransition implements Dump {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "AppTransition" : TAG_WM;
-    private static final boolean DEBUG_APP_TRANSITIONS =
-            WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
-    private static final boolean DEBUG_ANIM = WindowManagerDebugConfig.DEBUG_ANIM;
     private static final int CLIP_REVEAL_TRANSLATION_Y_DP = 8;
 
     /** Not set up for a transition. */
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 8292997..e046a77 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -247,7 +247,7 @@
         thumbnailTransformation.getMatrix().getValues(tmpFloats);
         if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
                 "thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
-                + ", " + tmpFloats[Matrix.MTRANS_Y], null);
+                + ", " + tmpFloats[Matrix.MTRANS_Y]);
         thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
         if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
                 "thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
@@ -255,7 +255,7 @@
                 + " matrix=[" + tmpFloats[Matrix.MSCALE_X]
                 + "," + tmpFloats[Matrix.MSKEW_Y]
                 + "][" + tmpFloats[Matrix.MSKEW_X]
-                + "," + tmpFloats[Matrix.MSCALE_Y] + "]", null);
+                + "," + tmpFloats[Matrix.MSCALE_Y] + "]");
         thumbnail.setAlpha(thumbnailTransformation.getAlpha());
         if (thumbnailForceAboveLayer > 0) {
             thumbnail.setLayer(thumbnailForceAboveLayer + 1);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 751f871..785f166 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -67,6 +67,7 @@
     // Whether we're performing an entering animation with a saved surface.
     boolean mAnimatingWithSavedSurface;
 
+
     Task mTask;
     boolean appFullscreen;
     int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -404,6 +405,17 @@
         }
     }
 
+    void setReplacingChildren() {
+        if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + appWindowToken
+                + " with replacing child windows.");
+        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
+            final WindowState w = allAppWindows.get(i);
+            if (w.isChildWindow()) {
+                w.setReplacing(false /* animate */);
+            }
+        }
+    }
+
     void resetReplacingWindows() {
         if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Resetting app token " + appWindowToken
                 + " of replacing window marks.");
@@ -477,6 +489,15 @@
      */
     void unfreezeBounds() {
         mFrozenBounds.remove();
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            final WindowState win = windows.get(i);
+            win.mLayoutNeeded = true;
+            win.setDisplayLayoutNeeded();
+            if (!service.mResizingWindows.contains(win)) {
+                service.mResizingWindows.add(win);
+            }
+        }
+        service.mWindowPlacerLocked.performSurfacePlacement();
     }
 
     @Override
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/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a9025bd..0c429e5 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -222,6 +222,10 @@
         out.set(left, top, left + width, top + height);
     }
 
+    void getContentRect(Rect out) {
+        out.set(mContentRect);
+    }
+
     /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
     void attachStack(TaskStack stack, boolean onTop) {
         if (stack.mStackId == HOME_STACK_ID) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 1b6957d..8aaf430 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -200,18 +200,22 @@
                 deferTransactionUntilFrame, outFrame);
     }
 
+    @Override
+    public void prepareToReplaceChildren(IBinder appToken) {
+        mService.setReplacingChildren(appToken);
+    }
+
     public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags,
             int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
-            Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Configuration
-                    outConfig,
-            Surface outSurface) {
+            Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
+            Configuration outConfig, Surface outSurface) {
         if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
         int res = mService.relayoutWindow(this, window, seq, attrs,
                 requestedWidth, requestedHeight, viewFlags, flags,
                 outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
-                outStableInsets, outsets, outConfig, outSurface);
+                outStableInsets, outsets, outBackdropFrame, outConfig, outSurface);
         if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                 + Binder.getCallingPid());
         return res;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 6bb3e20..d9667a1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -63,6 +63,9 @@
     private Rect mBounds = new Rect();
     final Rect mPreparedFrozenBounds = new Rect();
 
+    private Rect mPreScrollBounds = new Rect();
+    private boolean mScrollValid;
+
     // Bounds used to calculate the insets.
     private final Rect mTempInsetBounds = new Rect();
 
@@ -127,12 +130,25 @@
         int yOffset = 0;
         if (dockSide != DOCKED_INVALID) {
             mStack.getBounds(mTmpRect);
-            displayContent.getLogicalDisplayRect(mTmpRect2);
 
             if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
+                // The toast was originally placed at the bottom and centered. To place it
+                // at the bottom-center of the stack, we offset it horizontally by the diff
+                // between the center of the stack bounds vs. the center of the screen.
+                displayContent.getLogicalDisplayRect(mTmpRect2);
                 xOffset = mTmpRect.centerX() - mTmpRect2.centerX();
             } else if (dockSide == DOCKED_TOP) {
+                // The toast was originally placed at the bottom and centered. To place it
+                // at the bottom center of the top stack, we offset it vertically by the diff
+                // between the bottom of the stack bounds vs. the bottom of the content rect.
+                //
+                // Note here we use the content rect instead of the display rect, as we want
+                // the toast's distance to the dock divider (when it's placed at the top half)
+                // to be the same as it's distance to the top of the navigation bar (when it's
+                // placed at the bottom).
+
                 // We don't adjust for DOCKED_BOTTOM case since it's already at the bottom.
+                displayContent.getContentRect(mTmpRect2);
                 yOffset = mTmpRect2.bottom - mTmpRect.bottom;
             }
             mService.mH.obtainMessage(
@@ -258,19 +274,23 @@
             // Can't set to fullscreen if we don't have a display to get bounds from...
             return BOUNDS_CHANGE_NONE;
         }
-        if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
+        if (mPreScrollBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
             return BOUNDS_CHANGE_NONE;
         }
 
         int boundsChange = BOUNDS_CHANGE_NONE;
-        if (mBounds.left != bounds.left || mBounds.top != bounds.top) {
+        if (mPreScrollBounds.left != bounds.left || mPreScrollBounds.top != bounds.top) {
             boundsChange |= BOUNDS_CHANGE_POSITION;
         }
-        if (mBounds.width() != bounds.width() || mBounds.height() != bounds.height()) {
+        if (mPreScrollBounds.width() != bounds.width() || mPreScrollBounds.height() != bounds.height()) {
             boundsChange |= BOUNDS_CHANGE_SIZE;
         }
 
-        mBounds.set(bounds);
+
+        mPreScrollBounds.set(bounds);
+
+        resetScrollLocked();
+
         mRotation = rotation;
         if (displayContent != null) {
             displayContent.mDimLayerController.updateDimLayer(this);
@@ -331,6 +351,32 @@
         mPreparedFrozenBounds.set(mBounds);
     }
 
+    void resetScrollLocked() {
+        if (mScrollValid) {
+            mScrollValid = false;
+            applyScrollToAllWindows(0, 0);
+        }
+        mBounds.set(mPreScrollBounds);
+    }
+
+    void applyScrollToAllWindows(final int xOffset, final int yOffset) {
+        for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
+            final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
+            for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                final WindowState win = windows.get(winNdx);
+                win.mXOffset = xOffset;
+                win.mYOffset = yOffset;
+            }
+        }
+    }
+
+    void applyScrollToWindowIfNeeded(final WindowState win) {
+        if (mScrollValid) {
+            win.mXOffset = mBounds.left;
+            win.mYOffset = mBounds.top;
+        }
+    }
+
     boolean scrollLocked(Rect bounds) {
         // shift the task bound if it doesn't fully cover the stack area
         mStack.getDimBounds(mTmpRect);
@@ -352,21 +398,17 @@
             }
         }
 
-        if (bounds.equals(mBounds)) {
+        // We can stop here if we're already scrolling and the scrolled bounds not changed.
+        if (mScrollValid && bounds.equals(mBounds)) {
             return false;
         }
+
         // Normal setBounds() does not allow non-null bounds for fullscreen apps.
         // We only change bounds for the scrolling case without change it size,
         // on resizing path we should still want the validation.
         mBounds.set(bounds);
-        for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
-            final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
-            for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                final WindowState win = windows.get(winNdx);
-                win.mXOffset = bounds.left;
-                win.mYOffset = bounds.top;
-            }
-        }
+        mScrollValid = true;
+        applyScrollToAllWindows(bounds.left, bounds.top);
         return true;
     }
 
@@ -383,7 +425,7 @@
     }
 
     /** Original bounds of the task if applicable, otherwise fullscreen rect. */
-    public void getBounds(Rect out) {
+    void getBounds(Rect out) {
         if (useCurrentBounds()) {
             // No need to adjust the output bounds if fullscreen or the docked stack is visible
             // since it is already what we want to represent to the rest of the system.
@@ -391,9 +433,8 @@
             return;
         }
 
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
-        // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
-        // system.
+        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack is
+        // not currently visible. Go ahead a represent it as fullscreen to the rest of the system.
         mStack.getDisplayContent().getLogicalDisplayRect(out);
     }
 
@@ -481,19 +522,25 @@
             return;
         }
 
-        // Device rotation changed. We don't want the task to move around on the screen when
-        // this happens, so update the task bounds so it stays in the same place.
-        mTmpRect2.set(mBounds);
+        // Device rotation changed.
+        // - Reset the bounds to the pre-scroll bounds as whatever scrolling was done is no longer
+        // valid.
+        // - Rotate the bounds and notify activity manager if the task can be resized independently
+        // from its stack. The stack will take care of task rotation for the other case.
+        mTmpRect2.set(mPreScrollBounds);
+
+        if (!StackId.isTaskResizeAllowed(mStack.mStackId)) {
+            setBounds(mTmpRect2, mOverrideConfig);
+            return;
+        }
+
         displayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
         if (setBounds(mTmpRect2, mOverrideConfig) != BOUNDS_CHANGE_NONE) {
-            // Post message to inform activity manager of the bounds change simulating
-            // a one-way call. We do this to prevent a deadlock between window manager
-            // lock and activity manager lock been held. Only tasks within the freeform stack
-            // are resizeable independently of their stack resizing.
-            if (mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
-                mService.mH.sendMessage(mService.mH.obtainMessage(
-                        RESIZE_TASK, mTaskId, RESIZE_MODE_SYSTEM_SCREEN_ROTATION, mBounds));
-            }
+            // Post message to inform activity manager of the bounds change simulating a one-way
+            // call. We do this to prevent a deadlock between window manager lock and activity
+            // manager lock been held.
+            mService.mH.obtainMessage(RESIZE_TASK, mTaskId,
+                    RESIZE_MODE_SYSTEM_SCREEN_ROTATION, mPreScrollBounds).sendToTarget();
         }
     }
 
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/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index e75780f..a75f2c9 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManager.StackId;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Debug;
 import android.util.EventLog;
@@ -38,6 +37,7 @@
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_LEFT;
@@ -89,6 +89,7 @@
 
     /** Detach this stack from its display when animation completes. */
     boolean mDeferDetach;
+    private boolean mUpdateBoundsAfterRotation = false;
 
     TaskStack(WindowManagerService service, int stackId) {
         mService = service;
@@ -104,12 +105,6 @@
         return mTasks;
     }
 
-    void resizeWindows() {
-        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-            mTasks.get(taskNdx).resizeWindows();
-        }
-    }
-
     /**
      * Set the bounds of the stack and its containing tasks.
      * @param stackBounds New stack bounds. Passing in null sets the bounds to fullscreen.
@@ -136,11 +131,11 @@
                     // it might no longer fully cover the stack area.
                     // Save the old bounds and re-apply the scroll. This adjusts the bounds to
                     // fit the new stack bounds.
+                    task.resizeLocked(bounds, config, false /* forced */);
                     task.getBounds(mTmpRect);
-                    task.setBounds(bounds, config);
                     task.scrollLocked(mTmpRect);
                 } else {
-                    task.setBounds(bounds, config);
+                    task.resizeLocked(bounds, config, false /* forced */);
                     task.setTempInsetBounds(
                             taskTempInsetBounds != null ? taskTempInsetBounds.get(task.mTaskId)
                                     : null);
@@ -239,6 +234,7 @@
     }
 
     void updateDisplayInfo(Rect bounds) {
+        mUpdateBoundsAfterRotation = false;
         if (mDisplayContent != null) {
             for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
                 mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent);
@@ -248,6 +244,7 @@
             } else if (mFullscreen) {
                 setBounds(null);
             } else {
+                mUpdateBoundsAfterRotation = true;
                 mTmpRect2.set(mBounds);
                 final int newRotation = mDisplayContent.getDisplayInfo().rotation;
                 if (mRotation == newRotation) {
@@ -265,6 +262,10 @@
      * yet.
      */
     void updateBoundsAfterRotation() {
+        if (!mUpdateBoundsAfterRotation) {
+            return;
+        }
+        mUpdateBoundsAfterRotation = false;
         final int newRotation = getDisplayInfo().rotation;
         mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
         if (mStackId == DOCKED_STACK_ID) {
@@ -359,6 +360,10 @@
                 "positionTask: task=" + task + " position=" + position);
         mTasks.add(position, task);
 
+        // If we are moving the task across stacks, the scroll is no longer valid.
+        if (task.mStack != this) {
+            task.resetScrollLocked();
+        }
         task.mStack = this;
         task.updateDisplayInfo(mDisplayContent);
         boolean toTop = position == mTasks.size() - 1;
@@ -480,7 +485,7 @@
         }
     }
 
-    void getStackDockedModeBoundsLocked(Rect outBounds) {
+    void getStackDockedModeBoundsLocked(Rect outBounds, boolean ignoreVisibilityOnKeyguardShowing) {
         if (!StackId.isResizeableByDockedStack(mStackId) || mDisplayContent == null) {
             outBounds.set(mBounds);
             return;
@@ -492,11 +497,11 @@
             throw new IllegalStateException(
                     "Calling getStackDockedModeBoundsLocked() when there is no docked stack.");
         }
-        if (!dockedStack.isVisibleLocked()) {
+        if (!dockedStack.isVisibleLocked(ignoreVisibilityOnKeyguardShowing)) {
             // The docked stack is being dismissed, but we caught before it finished being
             // dismissed. In that case we want to treat it as if it is not occupying any space and
             // let others occupy the whole display.
-            mDisplayContent.getLogicalDisplayRect(mTmpRect);
+            mDisplayContent.getLogicalDisplayRect(outBounds);
             return;
         }
 
@@ -539,20 +544,32 @@
                 outBounds.set(mService.mDockedStackCreateBounds);
                 return;
             }
-            // The initial bounds of the docked stack when it is created half the screen space and
-            // its bounds can be adjusted after that. The bounds of all other stacks are adjusted
-            // to occupy whatever screen space the docked stack isn't occupying.
+
+            // The initial bounds of the docked stack when it is created about half the screen space
+            // and its bounds can be adjusted after that. The bounds of all other stacks are
+            // adjusted to occupy whatever screen space the docked stack isn't occupying.
+            final DisplayInfo di = mDisplayContent.getDisplayInfo();
+            mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+                    mTmpRect2);
+            final int position = new DividerSnapAlgorithm(mService.mContext.getResources(),
+                    0 /* minFlingVelocityPxPerSecond */,
+                    di.logicalWidth,
+                    di.logicalHeight,
+                    dockDividerWidth,
+                    mService.mCurConfiguration.orientation == ORIENTATION_PORTRAIT,
+                    mTmpRect2).getMiddleTarget().position;
+
             if (dockOnTopOrLeft) {
                 if (splitHorizontally) {
-                    outBounds.right = displayRect.centerX() - dockDividerWidth / 2;
+                    outBounds.right = position;
                 } else {
-                    outBounds.bottom = displayRect.centerY() - dockDividerWidth / 2;
+                    outBounds.bottom = position;
                 }
             } else {
                 if (splitHorizontally) {
-                    outBounds.left = displayRect.centerX() + dockDividerWidth / 2;
+                    outBounds.left = position - dockDividerWidth;
                 } else {
-                    outBounds.top = displayRect.centerY() + dockDividerWidth / 2;
+                    outBounds.top = position - dockDividerWidth;
                 }
             }
             return;
@@ -765,10 +782,19 @@
     }
 
     boolean isVisibleLocked() {
+        return isVisibleLocked(false);
+    }
+
+    boolean isVisibleLocked(boolean ignoreVisibilityOnKeyguardShowing) {
         final boolean keyguardOn = mService.mPolicy.isKeyguardShowingOrOccluded();
         if (keyguardOn && !StackId.isAllowedOverLockscreen(mStackId)) {
-            return false;
+            // The keyguard is showing and the stack shouldn't show on top of the keyguard.
+            // We return false for visibility except in cases where the caller wants us to return
+            // true for visibility when the keyguard is showing. One example, is if the docked
+            // is being resized due to orientation while the keyguard is on.
+            return ignoreVisibilityOnKeyguardShowing;
         }
+
         for (int i = mTasks.size() - 1; i >= 0; i--) {
             Task task = mTasks.get(i);
             for (int j = task.mAppTokens.size() - 1; j >= 0; j--) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 4c3a422..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;
@@ -71,6 +71,6 @@
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_VERBOSE_TRANSACTIONS = false && SHOW_TRANSACTIONS;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
-    static final boolean HIDE_STACK_CRAWLS = true;
+    static final boolean SHOW_STACK_CRAWLS = false;
     static final boolean DEBUG_WINDOW_CROP = false;
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 685df25..4b0015e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -20,7 +20,6 @@
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
@@ -57,7 +56,6 @@
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.Process;
-import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
@@ -119,6 +117,7 @@
 
 import com.android.internal.R;
 import com.android.internal.app.IAssistScreenshotReceiver;
+import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
@@ -219,7 +218,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
-import static com.android.server.wm.WindowManagerDebugConfig.HIDE_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -1501,7 +1500,7 @@
         if (w != null) {
             if (willMove) {
                 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
-                        + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
+                        + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
                 mInputMethodTarget = w;
                 mInputMethodTargetWaitingAnim = false;
                 if (w.mAppToken != null) {
@@ -1515,7 +1514,7 @@
         }
         if (willMove) {
             if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to null."
-                    + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
+                    + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
             mInputMethodTarget = null;
             mLayersController.setInputMethodAnimLayerAdjustment(0);
         }
@@ -2390,22 +2389,27 @@
         }
     }
 
-    static void logSurface(WindowState w, String msg, RuntimeException where) {
+    static void logSurface(WindowState w, String msg, boolean withStackTrace) {
         String str = "  SURFACE " + msg + ": " + w;
-        if (where != null) {
-            Slog.i(TAG_WM, str, where);
+        if (withStackTrace) {
+            logWithStack(TAG, str);
         } else {
             Slog.i(TAG_WM, str);
         }
     }
 
-    static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) {
+    static void logSurface(SurfaceControl s, String title, String msg) {
         String str = "  SURFACE " + s + ": " + msg + " / " + title;
-        if (where != null) {
-            Slog.i(TAG_WM, str, where);
-        } else {
-            Slog.i(TAG_WM, str);
+        Slog.i(TAG_WM, str);
+    }
+
+    static void logWithStack(String tag, String s) {
+        RuntimeException e = null;
+        if (SHOW_STACK_CRAWLS) {
+            e = new RuntimeException();
+            e.fillInStackTrace();
         }
+        Slog.i(tag, s, e);
     }
 
     void setTransparentRegionWindow(Session session, IWindow client, Region region) {
@@ -2414,7 +2418,7 @@
             synchronized (mWindowMap) {
                 WindowState w = windowForClientLocked(session, client, false);
                 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "transparentRegionHint=" + region, null);
+                        "transparentRegionHint=" + region, false);
 
                 if ((w != null) && w.mHasSurface) {
                     w.mWinAnimator.setTransparentRegionHintLocked(region);
@@ -2560,8 +2564,8 @@
             WindowManager.LayoutParams attrs, int requestedWidth,
             int requestedHeight, int viewVisibility, int flags,
             Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
-            Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig,
-            Surface outSurface) {
+            Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
+            Configuration outConfig, Surface outSurface) {
         int result = 0;
         boolean configChanged;
         boolean hasStatusBarPermission =
@@ -2689,7 +2693,14 @@
                     final boolean notExitingOrAnimating =
                             !win.mExiting && !win.isAnimatingWithSavedSurface();
                     result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0;
-                    if (notExitingOrAnimating) {
+                    // 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
+                    // application window during the tear down process. If we satisfied
+                    // 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);
 
@@ -2748,6 +2759,7 @@
             outVisibleInsets.set(win.mVisibleInsets);
             outStableInsets.set(win.mStableInsets);
             outOutsets.set(win.mOutsets);
+            outBackdropFrame.set(win.getBackdropFrame(win.mFrame));
             if (localLOGV) Slog.v(
                 TAG_WM, "Relayout given client " + client.asBinder()
                 + ", requestedWidth=" + requestedWidth
@@ -2868,7 +2880,12 @@
                 result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
             }
         }
-        result |= win.isDragResizing() ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0;
+        final boolean freeformResizing = win.isDragResizing()
+                && win.getResizeMode() == WindowState.DRAG_RESIZE_MODE_FREEFORM;
+        final boolean dockedResizing = win.isDragResizing()
+                && win.getResizeMode() == WindowState.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+        result |= freeformResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM : 0;
+        result |= dockedResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED : 0;
         if (win.isAnimatingWithSavedSurface()) {
             // If we're animating with a saved surface now, request client to report draw.
             // We still need to know when the real thing is drawn.
@@ -2883,9 +2900,10 @@
         try {
             synchronized (mWindowMap) {
                 WindowState win = windowForClientLocked(session, client, false);
-                if (win == null) {
+                if (win == null || win.mWillReplaceWindow) {
                     return;
                 }
+
                 win.mWinAnimator.destroyDeferredSurfaceLocked();
             }
         } finally {
@@ -2983,14 +3001,7 @@
                     mCurConfiguration.orientation, frame, insets, surfaceInsets, isVoiceInteraction,
                     !fullscreen, atoken.mTask.mTaskId);
             if (a != null) {
-                if (DEBUG_ANIM) {
-                    RuntimeException e = null;
-                    if (!HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
-                    }
-                    Slog.v(TAG_WM, "Loaded animation " + a + " for " + atoken, e);
-                }
+                if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + atoken);
                 final int containingWidth = frame.width();
                 final int containingHeight = frame.height();
                 atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight,
@@ -4299,16 +4310,8 @@
     }
 
     private void startAppFreezingScreenLocked(AppWindowToken wtoken) {
-        if (DEBUG_ORIENTATION) {
-            RuntimeException e = null;
-            if (!HIDE_STACK_CRAWLS) {
-                e = new RuntimeException();
-                e.fillInStackTrace();
-            }
-            Slog.i(TAG_WM, "Set freezing of " + wtoken.appToken
-                    + ": hidden=" + wtoken.hidden + " freezing="
-                    + wtoken.mAppAnimator.freezingScreen, e);
-        }
+        if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + wtoken.appToken + ": hidden="
+                + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
         if (!wtoken.hiddenRequested) {
             if (!wtoken.mAppAnimator.freezingScreen) {
                 wtoken.mAppAnimator.freezingScreen = true;
@@ -4794,11 +4797,12 @@
         }
     }
 
-    public void getStackDockedModeBounds(int stackId, Rect bounds) {
+    public void getStackDockedModeBounds(
+            int stackId, Rect bounds, boolean ignoreVisibilityOnKeyguardShowing) {
         synchronized (mWindowMap) {
             final TaskStack stack = mStackIdToStack.get(stackId);
             if (stack != null) {
-                stack.getStackDockedModeBoundsLocked(bounds);
+                stack.getStackDockedModeBoundsLocked(bounds, ignoreVisibilityOnKeyguardShowing);
                 return;
             }
             bounds.setEmpty();
@@ -4857,7 +4861,6 @@
             }
             if (stack.setBounds(bounds, configs, taskBounds, taskTempInsetBounds)
                     && stack.isVisibleLocked()) {
-                stack.resizeWindows();
                 stack.getDisplayContent().layoutNeeded = true;
                 mWindowPlacerLocked.performSurfacePlacement();
             }
@@ -8926,7 +8929,7 @@
                                     + ws + " surface=" + wsa.mSurfaceController
                                     + " token=" + ws.mAppToken
                                     + " saved=" + ws.mAppToken.hasSavedSurface());
-                            if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
+                            if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
                             wsa.destroySurface();
                             ws.setHasSurface(false);
                             leakedSurface = true;
@@ -8972,7 +8975,7 @@
                 Slog.w(TAG_WM, "Looks like we have reclaimed some memory, clearing surface for retry.");
                 if (surfaceController != null) {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
-                            "RECOVER DESTROY", null);
+                            "RECOVER DESTROY", false);
                     surfaceController.destroyInTransaction();
                     winAnimator.mWin.setHasSurface(false);
                     scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
@@ -10189,6 +10192,27 @@
     }
 
     /**
+     * Hint to a token that its children will be replaced across activity relaunch.
+     * The children would otherwise be removed  shortly following this as the
+     * activity is torn down.
+     * @param token Application token for which the activity will be relaunched.
+     */
+    public void setReplacingChildren(IBinder token) {
+        AppWindowToken appWindowToken = null;
+        synchronized (mWindowMap) {
+            appWindowToken = findAppWindowToken(token);
+            if (appWindowToken == null || !appWindowToken.isVisible()) {
+                Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token "
+                        + token);
+                return;
+            }
+
+            appWindowToken.setReplacingChildren();
+            scheduleClearReplacingWindowIfNeeded(token, true /* replacing */);
+        }
+    }
+
+    /**
      * If we're replacing the window, schedule a timer to clear the replaced window
      * after a timeout, in case the replacing window is not coming.
      *
@@ -10269,6 +10293,14 @@
                 listener);
     }
 
+    @Override
+    public void requestAppKeyboardShortcuts(IResultReceiver receiver) {
+        try {
+            getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver);
+        } catch (RemoteException e) {
+        }
+    }
+
     private final class LocalService extends WindowManagerInternal {
         @Override
         public void requestTraversalFromDisplayManager() {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 058fa67..e8a02b0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -729,6 +729,9 @@
                 // will return the correct value to the renderer.
                 mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame);
                 mContentFrame.set(mFrame);
+                if (!mFrame.equals(mLastFrame)) {
+                    mMovedByResize = true;
+                }
             }
         } else {
             mContentFrame.set(Math.max(mContentFrame.left, frame.left),
@@ -752,15 +755,7 @@
                 Math.max(frame.right - mOverscanFrame.right, 0),
                 Math.max(frame.bottom - mOverscanFrame.bottom, 0));
 
-        mContentInsets.set(mContentFrame.left - frame.left,
-                mContentFrame.top - frame.top,
-                frame.right - mContentFrame.right,
-                frame.bottom - mContentFrame.bottom);
 
-        mVisibleInsets.set(mVisibleFrame.left - frame.left,
-                mVisibleFrame.top - frame.top,
-                frame.right - mVisibleFrame.right,
-                frame.bottom - mVisibleFrame.bottom);
 
         if (mAttrs.type == TYPE_DOCK_DIVIDER) {
 
@@ -770,7 +765,22 @@
                     Math.max(mStableFrame.top - mDisplayFrame.top, 0),
                     Math.max(mDisplayFrame.right - mStableFrame.right, 0),
                     Math.max(mDisplayFrame.bottom - mStableFrame.bottom, 0));
+
+            // The divider doesn't care about insets in any case, so set it to empty so we don't
+            // trigger a relayout when moving it.
+            mContentInsets.setEmpty();
+            mVisibleInsets.setEmpty();
         } else {
+            mContentInsets.set(mContentFrame.left - frame.left,
+                    mContentFrame.top - frame.top,
+                    frame.right - mContentFrame.right,
+                    frame.bottom - mContentFrame.bottom);
+
+            mVisibleInsets.set(mVisibleFrame.left - frame.left,
+                    mVisibleFrame.top - frame.top,
+                    frame.right - mVisibleFrame.right,
+                    frame.bottom - mVisibleFrame.bottom);
+
             mStableInsets.set(Math.max(mStableFrame.left - frame.left, 0),
                     Math.max(mStableFrame.top - frame.top, 0),
                     Math.max(frame.right - mStableFrame.right, 0),
@@ -1045,61 +1055,59 @@
     }
 
     /**
-     * Is this window visible?  It is not visible if there is no
-     * surface, or we are in the process of running an exit animation
-     * that will remove the surface, or its app token has been hidden.
+     * Does the minimal check for visibility. Callers generally want to use one of the public
+     * methods as they perform additional checks on the app token.
+     * TODO: See if there are other places we can use this check below instead of duplicating...
      */
-    @Override
-    public boolean isVisibleLw() {
-        final AppWindowToken atoken = mAppToken;
+    private boolean isVisibleUnchecked() {
         return mHasSurface && mPolicyVisibility && !mAttachedHidden
-                && (atoken == null || !atoken.hiddenRequested)
-                && !mExiting && !mDestroying;
+                && !mExiting && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
     }
 
     /**
-     * Like {@link #isVisibleLw}, but also counts a window that is currently
-     * "hidden" behind the keyguard as visible.  This allows us to apply
-     * things like window flags that impact the keyguard.
-     * XXX I am starting to think we need to have ANOTHER visibility flag
-     * for this "hidden behind keyguard" state rather than overloading
-     * mPolicyVisibility.  Ungh.
+     * Is this window visible?  It is not visible if there is no surface, or we are in the process
+     * of running an exit animation that will remove the surface, or its app token has been hidden.
+     */
+    @Override
+    public boolean isVisibleLw() {
+        return (mAppToken == null || !mAppToken.hiddenRequested) && isVisibleUnchecked();
+    }
+
+    /**
+     * Like {@link #isVisibleLw}, but also counts a window that is currently "hidden" behind the
+     * keyguard as visible.  This allows us to apply things like window flags that impact the
+     * keyguard. XXX I am starting to think we need to have ANOTHER visibility flag for this
+     * "hidden behind keyguard" state rather than overloading mPolicyVisibility.  Ungh.
      */
     @Override
     public boolean isVisibleOrBehindKeyguardLw() {
-        if (mRootToken.waitingToShow &&
-                mService.mAppTransition.isTransitionSet()) {
+        if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
             return false;
         }
         final AppWindowToken atoken = mAppToken;
         final boolean animating = atoken != null && atoken.mAppAnimator.animation != null;
         return mHasSurface && !mDestroying && !mExiting
                 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
-                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
-                                && !mRootToken.hidden)
+                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
                         || mWinAnimator.mAnimation != null || animating);
     }
 
     /**
-     * Is this window visible, ignoring its app token?  It is not visible
-     * if there is no surface, or we are in the process of running an exit animation
-     * that will remove the surface.
+     * Is this window visible, ignoring its app token? It is not visible if there is no surface,
+     * or we are in the process of running an exit animation that will remove the surface.
      */
     public boolean isWinVisibleLw() {
-        final AppWindowToken atoken = mAppToken;
-        return mHasSurface && mPolicyVisibility && !mAttachedHidden
-                && (atoken == null || !atoken.hiddenRequested || atoken.mAppAnimator.animating)
-                && !mExiting && !mDestroying;
+        return (mAppToken == null || !mAppToken.hiddenRequested || mAppToken.mAppAnimator.animating)
+                && isVisibleUnchecked();
     }
 
     /**
-     * The same as isVisible(), but follows the current hidden state of
-     * the associated app token, not the pending requested hidden state.
+     * The same as isVisible(), but follows the current hidden state of the associated app token,
+     * not the pending requested hidden state.
      */
     boolean isVisibleNow() {
-        return mHasSurface && mPolicyVisibility && !mAttachedHidden
-                && (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
-                && !mExiting && !mDestroying;
+        return (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
+                && isVisibleUnchecked();
     }
 
     /**
@@ -1158,8 +1166,7 @@
             return false;
         }
         return mHasSurface && mPolicyVisibility && !mDestroying
-                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
-                                && !mRootToken.hidden)
+                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
                         || mWinAnimator.mAnimation != null
                         || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null)));
     }
@@ -1179,8 +1186,7 @@
             return false;
         }
         return mHasSurface && !mDestroying
-                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
-                                && !mRootToken.hidden)
+                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
                         || mWinAnimator.mAnimation != null
                         || ((atoken != null) && (atoken.mAppAnimator.animation != null)
                                 && !mWinAnimator.isDummyAnimation()));
@@ -1469,10 +1475,8 @@
 
     void applyScrollIfNeeded() {
         final Task task = getTask();
-        if (task != null && task.isTwoFingerScrollMode()) {
-            task.getDimBounds(mTmpRect);
-            mXOffset = mTmpRect.left;
-            mYOffset = mTmpRect.top;
+        if (task != null) {
+            task.applyScrollToWindowIfNeeded(this);
         }
     }
 
@@ -1995,21 +1999,24 @@
         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
-    private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
-            Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-            Configuration newConfig) throws RemoteException {
-        DisplayInfo displayInfo = getDisplayInfo();
-        mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
+    Rect getBackdropFrame(Rect frame) {
         // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
         // start even if we haven't received the relayout window, so that the client requests
         // the relayout sooner. When dragging stops, backDropFrame needs to stay fullscreen
         // until the window to small size, otherwise the multithread renderer will shift last
         // one or more frame to wrong offset. So here we send fullscreen backdrop if either
         // isDragResizing() or isDragResizeChanged() is true.
+        DisplayInfo displayInfo = getDisplayInfo();
+        mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
         boolean resizing = isDragResizing() || isDragResizeChanged();
-        final Rect backDropFrame = (inFreeformWorkspace() || !resizing) ? frame : mTmpRect;
+        return (inFreeformWorkspace() || !resizing) ? frame : mTmpRect;
+    }
+
+    private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
+            Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
+            Configuration newConfig) throws RemoteException {
         mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets,
-                reportDraw, newConfig, backDropFrame);
+                reportDraw, newConfig, getBackdropFrame(frame));
     }
 
     public void registerFocusObserver(IWindowFocusObserver observer) {
@@ -2284,10 +2291,12 @@
 
     void transformFromScreenToSurfaceSpace(Rect rect) {
          if (mHScale >= 0) {
-            rect.right = rect.left + (int)((rect.right - rect.left) / mHScale);
+            rect.left = (int) (rect.left / mHScale);
+            rect.right = (int) (rect.right / mHScale);
         }
         if (mVScale >= 0) {
-            rect.bottom = rect.top + (int)((rect.bottom - rect.top) / mVScale);
+            rect.top = (int) (rect.top / mVScale);
+            rect.bottom = (int) (rect.bottom / mVScale);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 83ab190..da4e191 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -29,7 +29,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
-import static com.android.server.wm.WindowManagerDebugConfig.HIDE_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -37,6 +37,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
 import static com.android.server.wm.WindowManagerService.localLOGV;
+import static com.android.server.wm.WindowManagerService.logWithStack;
 import static com.android.server.wm.WindowState.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
 import static com.android.server.wm.WindowState.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
@@ -547,7 +548,7 @@
         if (mDestroyPreservedSurfaceUponRedraw) {
             return;
         }
-        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", null);
+        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", false);
         if (mSurfaceController != null) {
             mSurfaceController.setLayer(mAnimLayer + 1);
         }
@@ -665,13 +666,13 @@
                 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
                 WindowManagerService.logSurface(w, "CREATE pos=("
                         + w.mFrame.left + "," + w.mFrame.top + ") ("
-                        + width + "x" + height + "), layer=" + mAnimLayer + " HIDE", null);
+                        + width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
             }
 
             // Start a new transaction and apply position & offset.
             final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                    "POS " + mTmpSize.left + ", " + mTmpSize.top, null);
+                    "POS " + mTmpSize.left + ", " + mTmpSize.top, false);
             mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack,
                     mAnimLayer);
             mLastHidden = true;
@@ -758,25 +759,13 @@
             }
 
             try {
-                if (DEBUG_VISIBILITY) {
-                    RuntimeException e = null;
-                    if (!HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
-                    }
-                    Slog.w(TAG, "Window " + this + " destroying surface "
-                            + mSurfaceController + ", session " + mSession, e);
-                }
+                if (DEBUG_VISIBILITY) logWithStack(TAG, "Window " + this + " destroying surface "
+                        + mSurfaceController + ", session " + mSession);
                 if (mSurfaceDestroyDeferred) {
                     if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
                         if (mPendingDestroySurface != null) {
                             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-                                RuntimeException e = null;
-                                if (!HIDE_STACK_CRAWLS) {
-                                    e = new RuntimeException();
-                                    e.fillInStackTrace();
-                                }
-                                WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
+                                WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
                             }
                             mPendingDestroySurface.destroyInTransaction();
                         }
@@ -784,12 +773,7 @@
                     }
                 } else {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-                        RuntimeException e = null;
-                        if (!HIDE_STACK_CRAWLS) {
-                            e = new RuntimeException();
-                            e.fillInStackTrace();
-                        }
-                        WindowManagerService.logSurface(mWin, "DESTROY", null);
+                        WindowManagerService.logSurface(mWin, "DESTROY", true);
                     }
                     destroySurface();
                 }
@@ -820,12 +804,7 @@
         try {
             if (mPendingDestroySurface != null) {
                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-                    RuntimeException e = null;
-                    if (!HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
-                    }
-                    WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
+                    WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
                 }
                 mPendingDestroySurface.destroyInTransaction();
                 // Don't hide wallpaper if we're destroying a deferred surface
@@ -1308,7 +1287,7 @@
                     + " matrix=[" + mDsDx + "*" + w.mHScale
                     + "," + mDtDx + "*" + w.mVScale
                     + "][" + mDsDy + "*" + w.mHScale
-                    + "," + mDtDy + "*" + w.mVScale + "]", null);
+                    + "," + mDtDy + "*" + w.mVScale + "]", false);
 
             boolean prepared =
                 mSurfaceController.prepareToShowInTransaction(mShownAlpha, mAnimLayer,
@@ -1355,6 +1334,11 @@
                 }
             }
             w.mToken.hasVisible = true;
+
+            final Task task = w.getTask();
+            if (task != null) {
+                task.scheduleShowNonResizeableDockToastIfNeeded();
+            }
         }
     }
 
@@ -1513,10 +1497,6 @@
                 mWin.mAppToken.updateReportedVisibilityLocked();
             }
 
-            final Task task = mWin.getTask();
-            if (task != null) {
-                task.scheduleShowNonResizeableDockToastIfNeeded();
-            }
             return true;
         }
         return false;
@@ -1619,14 +1599,7 @@
                     + " transit=" + transit
                     + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
             if (a != null) {
-                if (DEBUG_ANIM) {
-                    RuntimeException e = null;
-                    if (!HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
-                    }
-                    Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
-                }
+                if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
                 setAnimation(a);
                 mAnimationIsEntrance = isEntrance;
             }
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 9675d2f..5674ca2 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -18,9 +18,7 @@
 
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
-import static com.android.server.wm.WindowManagerDebugConfig.HIDE_STACK_CRAWLS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index f77e5a6..ab6667a 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1197,7 +1197,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) {
diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp
index 3f074f5..c8e3946 100644
--- a/services/core/jni/com_android_server_lights_LightsService.cpp
+++ b/services/core/jni/com_android_server_lights_LightsService.cpp
@@ -113,11 +113,27 @@
         return ;
     }
 
+    uint32_t version = devices->lights[light]->common.version;
+
     memset(&state, 0, sizeof(light_state_t));
-    state.color = colorARGB;
-    state.flashMode = flashMode;
-    state.flashOnMS = onMS;
-    state.flashOffMS = offMS;
+
+    if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
+        if (light != LIGHT_INDEX_BACKLIGHT) {
+            ALOGE("Cannot set low-persistence mode for non-backlight device.");
+            return;
+        }
+        if (version < LIGHTS_DEVICE_API_VERSION_2_0) {
+            // HAL impl has not been upgraded to support this.
+            return;
+        }
+    } else {
+        // Only set non-brightness settings when not in low-persistence mode
+        state.color = colorARGB;
+        state.flashMode = flashMode;
+        state.flashOnMS = onMS;
+        state.flashOffMS = offMS;
+    }
+
     state.brightnessMode = brightnessMode;
 
     {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 380763a..a23e74b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -33,6 +33,7 @@
 import android.accounts.AccountManager;
 import android.annotation.NonNull;
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
@@ -82,6 +83,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
@@ -156,6 +158,7 @@
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Implementation of the device policy APIs.
@@ -254,6 +257,7 @@
     final IPackageManager mIPackageManager;
     final UserManager mUserManager;
     final UserManagerInternal mUserManagerInternal;
+    private final LockPatternUtils mLockPatternUtils;
 
     final LocalService mLocalService;
 
@@ -269,6 +273,46 @@
      */
     private boolean mHasFeature;
 
+    private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean();
+    private final AtomicBoolean mRemoteBugreportSharingAccepted = new AtomicBoolean();
+
+    private final Runnable mRemoteBugreportTimeoutRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if(mRemoteBugreportServiceIsActive.get()) {
+                onBugreportFailed();
+            }
+        }
+    };
+
+    private final BroadcastReceiver mRemoteBugreportFinishedReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_DISPATCH.equals(intent.getAction())
+                    && mRemoteBugreportServiceIsActive.get()) {
+                onBugreportFinished(intent);
+            }
+        }
+    };
+
+    private final BroadcastReceiver mRemoteBugreportConsentReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            mInjector.getNotificationManager().cancel(LOG_TAG,
+                    RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID);
+            if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED.equals(action)) {
+                onBugreportSharingAccepted();
+            } else if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_DECLINED
+                    .equals(action)) {
+                onBugreportSharingDeclined();
+            }
+            mContext.unregisterReceiver(mRemoteBugreportConsentReceiver);
+        }
+    };
+
     public static final class Lifecycle extends SystemService {
         private DevicePolicyManagerService mService;
 
@@ -342,6 +386,20 @@
             final String action = intent.getAction();
             final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                     getSendingUserId());
+
+            if (Intent.ACTION_BOOT_COMPLETED.equals(action)
+                    && userHandle == mOwners.getDeviceOwnerUserId()
+                    && getDeviceOwnerRemoteBugreportUri() != null) {
+                IntentFilter filterConsent = new IntentFilter();
+                filterConsent.addAction(
+                        RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_DECLINED);
+                filterConsent.addAction(
+                        RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED);
+                mContext.registerReceiver(mRemoteBugreportConsentReceiver, filterConsent);
+                mInjector.getNotificationManager().notify(
+                        LOG_TAG, RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
+                        RemoteBugreportUtils.buildRemoteBugreportConsentNotification(mContext));
+            }
             if (Intent.ACTION_BOOT_COMPLETED.equals(action)
                     || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) {
                 if (VERBOSE_LOG) {
@@ -1329,6 +1387,7 @@
         mIPackageManager = Preconditions.checkNotNull(injector.getIPackageManager());
 
         mLocalService = new LocalService();
+        mLockPatternUtils = new LockPatternUtils(mContext);
 
         mHasFeature = mContext.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
@@ -2178,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"
@@ -2573,10 +2633,16 @@
         }
     }
 
-    private boolean isAdminApiLevelPreN(@NonNull ComponentName who, int userHandle) {
+    private boolean isAdminApiLevelMOrBelow(@NonNull ComponentName who, int userHandle) {
         DeviceAdminInfo adminInfo = findAdmin(who, userHandle, false);
         return adminInfo.getActivityInfo().applicationInfo.targetSdkVersion
-                < Build.VERSION_CODES.N;
+                <= Build.VERSION_CODES.M;
+    }
+
+    @Override
+    public boolean isSeparateProfileChallengeAllowed(int userHandle) {
+        ComponentName profileOwner = getProfileOwner(userHandle);
+        return !isAdminApiLevelMOrBelow(profileOwner, userHandle);
     }
 
     @Override
@@ -2618,7 +2684,7 @@
                 return admin != null ? admin.passwordQuality : mode;
             }
 
-            if (LockPatternUtils.isSeparateWorkChallengeEnabled() && !parent) {
+            if (isSeparateProfileChallengeEnabled(userHandle) && !parent) {
                 // If a Work Challenge is in use, only return its restrictions.
                 DevicePolicyData policy = getUserDataUnchecked(userHandle);
                 final int N = policy.mAdminList.size();
@@ -2638,7 +2704,7 @@
                     // Only aggregate data for the parent profile plus the non-work challenge
                     // enabled profiles.
                     if (!(userInfo.isManagedProfile()
-                            && LockPatternUtils.isSeparateWorkChallengeEnabled())) {
+                            && isSeparateProfileChallengeEnabled(userInfo.id))) {
                         DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
                         final int N = policy.mAdminList.size();
                         for (int i = 0; i < N; i++) {
@@ -2654,6 +2720,15 @@
         }
     }
 
+    private boolean isSeparateProfileChallengeEnabled(int userHandle) {
+        long ident = mInjector.binderClearCallingIdentity();
+        try {
+            return mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
+        }
+    }
+
     @Override
     public void setPasswordMinimumLength(ComponentName who, int length) {
         if (!mHasFeature) {
@@ -3224,8 +3299,8 @@
                     getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
             ComponentName adminComponentName = admin.info.getComponent();
             // TODO: Include the Admin sdk level check in LockPatternUtils check.
-            ComponentName who = !isAdminApiLevelPreN(adminComponentName, userHandle)
-                    && LockPatternUtils.isSeparateWorkChallengeEnabled()
+            ComponentName who = !isAdminApiLevelMOrBelow(adminComponentName, userHandle)
+                    && isSeparateProfileChallengeEnabled(userHandle)
                         ? adminComponentName : null;
             if (policy.mActivePasswordQuality < getPasswordQuality(who, userHandle, parent)
                     || policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
@@ -3393,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
@@ -3899,6 +3977,42 @@
         }
     }
 
+    @Override
+    public boolean setAlwaysOnVpnPackage(ComponentName admin, String vpnPackage)
+            throws SecurityException {
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+        }
+
+        final int userId = mInjector.userHandleGetCallingUserId();
+        final long token = mInjector.binderClearCallingIdentity();
+        try{
+            ConnectivityManager connectivityManager = (ConnectivityManager)
+                    mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+            return connectivityManager.setAlwaysOnVpnPackageForUser(userId, vpnPackage);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public String getAlwaysOnVpnPackage(ComponentName admin)
+            throws SecurityException {
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+        }
+
+        final int userId = mInjector.userHandleGetCallingUserId();
+        final long token = mInjector.binderClearCallingIdentity();
+        try{
+            ConnectivityManager connectivityManager = (ConnectivityManager)
+                    mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+            return connectivityManager.getAlwaysOnVpnPackageForUser(userId);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(token);
+        }
+    }
+
     private void wipeDataLocked(boolean wipeExtRequested, String reason) {
         if (wipeExtRequested) {
             StorageManager sm = (StorageManager) mContext.getSystemService(
@@ -4028,7 +4142,7 @@
         }
         enforceFullCrossUsersPermission(userHandle);
         // Managed Profile password can only be changed when per user encryption is present.
-        if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+        if (!isSeparateProfileChallengeEnabled(userHandle)) {
             enforceNotManagedProfile(userHandle, "set the active password");
         }
 
@@ -4055,7 +4169,7 @@
                 setExpirationAlarmCheckLocked(mContext, policy);
 
                 // Send a broadcast to each profile using this password as its primary unlock.
-                if (LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
                     sendAdminCommandLocked(
                             DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
                             DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
@@ -4541,6 +4655,212 @@
         }
     }
 
+    private void ensureDeviceOwnerManagingSingleUser(ComponentName who) throws SecurityException {
+        synchronized (this) {
+            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+        }
+        final long callingIdentity = mInjector.binderClearCallingIdentity();
+        try {
+            if (mInjector.userManagerIsSplitSystemUser()) {
+                // In split system user mode, only allow the case where the device owner is managing
+                // the only non-system user of the device
+                if (mUserManager.getUserCount() > 2
+                        || mOwners.getDeviceOwnerUserId() == UserHandle.USER_SYSTEM) {
+                    throw new SecurityException(
+                            "There should only be one user, managed by Device Owner");
+                }
+            } else if (mUserManager.getUserCount() > 1) {
+                throw new SecurityException(
+                        "There should only be one user, managed by Device Owner");
+            }
+        } finally {
+            mInjector.binderRestoreCallingIdentity(callingIdentity);
+        }
+    }
+
+    @Override
+    public boolean requestBugreport(ComponentName who) {
+        if (!mHasFeature) {
+            return false;
+        }
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        ensureDeviceOwnerManagingSingleUser(who);
+
+        if (mRemoteBugreportServiceIsActive.get()
+                || (getDeviceOwnerRemoteBugreportUri() != null)) {
+            Slog.d(LOG_TAG, "Remote bugreport wasn't started because there's already one running.");
+            return false;
+        }
+
+        final long callingIdentity = mInjector.binderClearCallingIdentity();
+        try {
+            ActivityManagerNative.getDefault().requestBugReport(
+                    ActivityManager.BUGREPORT_OPTION_REMOTE);
+
+            mRemoteBugreportServiceIsActive.set(true);
+            mRemoteBugreportSharingAccepted.set(false);
+            registerRemoteBugreportReceivers();
+            mInjector.getNotificationManager().notify(
+                    LOG_TAG, RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
+                    RemoteBugreportUtils.buildRemoteBugreportConsentNotification(mContext));
+            mInjector.getNotificationManager().notify(
+                    LOG_TAG, RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID,
+                    RemoteBugreportUtils.buildRemoteBugreportInProgressNotification(mContext,
+                            /* canCancelBugReport */ true));
+            mHandler.postDelayed(mRemoteBugreportTimeoutRunnable,
+                    RemoteBugreportUtils.REMOTE_BUGREPORT_TIMEOUT_MILLIS);
+            return true;
+        } catch (RemoteException re) {
+            // should never happen
+            Slog.e(LOG_TAG, "Failed to make remote calls to start bugreportremote service", re);
+            return false;
+        } finally {
+            mInjector.binderRestoreCallingIdentity(callingIdentity);
+        }
+    }
+
+    private synchronized void sendDeviceOwnerCommand(String action, Bundle extras) {
+        Intent intent = new Intent(action);
+        intent.setComponent(mOwners.getDeviceOwnerComponent());
+        if (extras != null) {
+            intent.putExtras(extras);
+        }
+        mContext.sendBroadcastAsUser(intent, UserHandle.of(mOwners.getDeviceOwnerUserId()));
+    }
+
+    private synchronized String getDeviceOwnerRemoteBugreportUri() {
+        return mOwners.getDeviceOwnerRemoteBugreportUri();
+    }
+
+    private synchronized void setDeviceOwnerRemoteBugreportUriAndHash(String bugreportUri,
+            String bugreportHash) {
+        mOwners.setDeviceOwnerRemoteBugreportUriAndHash(bugreportUri, bugreportHash);
+    }
+
+    private void registerRemoteBugreportReceivers() {
+        try {
+            IntentFilter filterFinished = new IntentFilter(
+                    RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_DISPATCH,
+                    RemoteBugreportUtils.BUGREPORT_MIMETYPE);
+            mContext.registerReceiver(mRemoteBugreportFinishedReceiver, filterFinished);
+        } catch (IntentFilter.MalformedMimeTypeException e) {
+            // should never happen, as setting a constant
+            Slog.w(LOG_TAG, "Failed to set type " + RemoteBugreportUtils.BUGREPORT_MIMETYPE, e);
+        }
+        IntentFilter filterConsent = new IntentFilter();
+        filterConsent.addAction(RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_DECLINED);
+        filterConsent.addAction(RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED);
+        mContext.registerReceiver(mRemoteBugreportConsentReceiver, filterConsent);
+    }
+
+    private void onBugreportFinished(Intent intent) {
+        mHandler.removeCallbacks(mRemoteBugreportTimeoutRunnable);
+        mRemoteBugreportServiceIsActive.set(false);
+        mInjector.getNotificationManager().cancel(LOG_TAG,
+                RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID);
+        Uri bugreportUri = intent.getData();
+        String bugreportUriString = null;
+        if (bugreportUri != null) {
+            bugreportUriString = bugreportUri.toString();
+        }
+        String bugreportHash = intent.getStringExtra(
+                RemoteBugreportUtils.EXTRA_REMOTE_BUGREPORT_HASH);
+        if (mRemoteBugreportSharingAccepted.get()) {
+            shareBugreportWithDeviceOwnerIfExists(bugreportUriString, bugreportHash);
+        } else {
+            setDeviceOwnerRemoteBugreportUriAndHash(bugreportUriString, bugreportHash);
+        }
+        mContext.unregisterReceiver(mRemoteBugreportFinishedReceiver);
+    }
+
+    private void onBugreportFailed() {
+        mRemoteBugreportServiceIsActive.set(false);
+        mInjector.systemPropertiesSet(RemoteBugreportUtils.CTL_STOP,
+                RemoteBugreportUtils.REMOTE_BUGREPORT_SERVICE);
+        mRemoteBugreportSharingAccepted.set(false);
+        setDeviceOwnerRemoteBugreportUriAndHash(null, null);
+        mInjector.getNotificationManager().cancel(LOG_TAG,
+                RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID);
+        mInjector.getNotificationManager().cancel(LOG_TAG,
+                RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID);
+        Bundle extras = new Bundle();
+        extras.putInt(DeviceAdminReceiver.EXTRA_BUGREPORT_FAILURE_REASON,
+                DeviceAdminReceiver.BUGREPORT_FAILURE_FAILED_COMPLETING);
+        sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_BUGREPORT_FAILED, extras);
+        mContext.unregisterReceiver(mRemoteBugreportConsentReceiver);
+        mContext.unregisterReceiver(mRemoteBugreportFinishedReceiver);
+    }
+
+    private void onBugreportSharingAccepted() {
+        mRemoteBugreportSharingAccepted.set(true);
+        String bugreportUriString = null;
+        String bugreportHash = null;
+        synchronized (this) {
+            bugreportUriString = getDeviceOwnerRemoteBugreportUri();
+            bugreportHash = mOwners.getDeviceOwnerRemoteBugreportHash();
+        }
+        if (bugreportUriString != null) {
+            shareBugreportWithDeviceOwnerIfExists(bugreportUriString, bugreportHash);
+        } else if (mRemoteBugreportServiceIsActive.get()) {
+            mInjector.getNotificationManager().notify(LOG_TAG,
+                    RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID,
+                    RemoteBugreportUtils.buildRemoteBugreportInProgressNotification(mContext,
+                            /* canCancelBugReport */ false));
+        }
+    }
+
+    private void onBugreportSharingDeclined() {
+        if (mRemoteBugreportServiceIsActive.get()) {
+            mInjector.systemPropertiesSet(RemoteBugreportUtils.CTL_STOP,
+                    RemoteBugreportUtils.REMOTE_BUGREPORT_SERVICE);
+            mRemoteBugreportServiceIsActive.set(false);
+            mHandler.removeCallbacks(mRemoteBugreportTimeoutRunnable);
+            mContext.unregisterReceiver(mRemoteBugreportFinishedReceiver);
+        }
+        mRemoteBugreportSharingAccepted.set(false);
+        setDeviceOwnerRemoteBugreportUriAndHash(null, null);
+        mInjector.getNotificationManager().cancel(LOG_TAG,
+                RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID);
+        sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_BUGREPORT_SHARING_DECLINED, null);
+    }
+
+    private void shareBugreportWithDeviceOwnerIfExists(String bugreportUriString,
+            String bugreportHash) {
+        ParcelFileDescriptor pfd = null;
+        try {
+            if (bugreportUriString == null) {
+                throw new FileNotFoundException();
+            }
+            Uri bugreportUri = Uri.parse(bugreportUriString);
+            pfd = mContext.getContentResolver().openFileDescriptor(bugreportUri, "r");
+
+            synchronized (this) {
+                Intent intent = new Intent(DeviceAdminReceiver.ACTION_BUGREPORT_SHARE);
+                intent.setComponent(mOwners.getDeviceOwnerComponent());
+                intent.setDataAndType(bugreportUri, RemoteBugreportUtils.BUGREPORT_MIMETYPE);
+                intent.putExtra(DeviceAdminReceiver.EXTRA_BUGREPORT_HASH, bugreportHash);
+                mContext.grantUriPermission(mOwners.getDeviceOwnerComponent().getPackageName(),
+                        bugreportUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                mContext.sendBroadcastAsUser(intent, UserHandle.of(mOwners.getDeviceOwnerUserId()));
+            }
+        } catch (FileNotFoundException e) {
+            Bundle extras = new Bundle();
+            extras.putInt(DeviceAdminReceiver.EXTRA_BUGREPORT_FAILURE_REASON,
+                    DeviceAdminReceiver.BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE);
+            sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_BUGREPORT_FAILED, extras);
+        } finally {
+            try {
+                if (pfd != null) {
+                    pfd.close();
+                }
+            } catch (IOException ex) {
+                // Ignore
+            }
+            mRemoteBugreportSharingAccepted.set(false);
+            setDeviceOwnerRemoteBugreportUriAndHash(null, null);
+        }
+    }
+
     /**
      * Disables all device cameras according to the specified admin.
      */
@@ -4647,10 +4967,9 @@
 
                 UserInfo user = mUserManager.getUserInfo(userHandle);
                 final List<UserInfo> profiles;
-                if (user.isManagedProfile() || LockPatternUtils.isSeparateWorkChallengeEnabled()) {
-                    // If we are being asked about a managed profile or the main user profile has a
-                    // separate lock from the work profile, just return keyguard features disabled
-                    // by admins in the profile.
+                if (user.isManagedProfile()) {
+                    // If we are being asked about a managed profile, just return keyguard features
+                    // disabled by admins in the profile.
                     profiles = Collections.singletonList(user);
                 } else {
                     // Otherwise return those set by admins in the user
@@ -4669,9 +4988,11 @@
                             // If we are being asked explictly about this user
                             // return all disabled features even if its a managed profile.
                             which |= admin.disabledKeyguardFeatures;
-                        } else {
+                        } else if (!isSeparateProfileChallengeEnabled(
+                                userInfo.id)) {
                             // Otherwise a managed profile is only allowed to disable
-                            // some features on the parent user.
+                            // some features on the parent user, and we only aggregate them if
+                            // it doesn't have its own challenge.
                             which |= (admin.disabledKeyguardFeatures
                                     & PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER);
                         }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index f7de0b3..880f810 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -77,6 +77,8 @@
     private static final String ATTR_NAME = "name";
     private static final String ATTR_PACKAGE = "package";
     private static final String ATTR_COMPONENT_NAME = "component";
+    private static final String ATTR_REMOTE_BUGREPORT_URI = "remoteBugreportUri";
+    private static final String ATTR_REMOTE_BUGREPORT_HASH = "remoteBugreportHash";
     private static final String ATTR_USERID = "userId";
     private static final String ATTR_USER_RESTRICTIONS_MIGRATED = "userRestrictionsMigrated";
 
@@ -161,6 +163,14 @@
         return mDeviceOwner != null ? mDeviceOwner.admin : null;
     }
 
+    String getDeviceOwnerRemoteBugreportUri() {
+        return mDeviceOwner != null ? mDeviceOwner.remoteBugreportUri : null;
+    }
+
+    String getDeviceOwnerRemoteBugreportHash() {
+        return mDeviceOwner != null ? mDeviceOwner.remoteBugreportHash : null;
+    }
+
     void setDeviceOwner(ComponentName admin, String ownerName, int userId) {
         if (userId < 0) {
             Slog.e(TAG, "Invalid user id for device owner user: " + userId);
@@ -175,7 +185,8 @@
     // userRestrictionsMigrated should always be true.
     void setDeviceOwnerWithRestrictionsMigrated(ComponentName admin, String ownerName, int userId,
             boolean userRestrictionsMigrated) {
-        mDeviceOwner = new OwnerInfo(ownerName, admin, userRestrictionsMigrated);
+        mDeviceOwner = new OwnerInfo(ownerName, admin, userRestrictionsMigrated,
+                /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/ null);
         mDeviceOwnerUserId = userId;
 
         mUserManagerInternal.setDeviceManaged(true);
@@ -191,7 +202,8 @@
     void setProfileOwner(ComponentName admin, String ownerName, int userId) {
         // For a newly set PO, there's no need for migration.
         mProfileOwners.put(userId, new OwnerInfo(ownerName, admin,
-                /* userRestrictionsMigrated =*/ true));
+                /* userRestrictionsMigrated =*/ true, /* remoteBugreportUri =*/ null,
+                /* remoteBugreportHash =*/ null));
         mUserManagerInternal.setUserManaged(userId, true);
     }
 
@@ -266,6 +278,16 @@
         writeDeviceOwner();
     }
 
+    /** Sets the remote bugreport uri and hash, and also writes to the file. */
+    void setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri,
+            String remoteBugreportHash) {
+        if (mDeviceOwner != null) {
+            mDeviceOwner.remoteBugreportUri = remoteBugreportUri;
+            mDeviceOwner.remoteBugreportHash = remoteBugreportHash;
+        }
+        writeDeviceOwner();
+    }
+
     /** Sets the user restrictions migrated flag, and also writes to the file.  */
     void setProfileOwnerUserRestrictionsMigrated(int userId) {
         OwnerInfo profileOwner = mProfileOwners.get(userId);
@@ -295,7 +317,8 @@
                     String name = parser.getAttributeValue(null, ATTR_NAME);
                     String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
                     mDeviceOwner = new OwnerInfo(name, packageName,
-                            /* userRestrictionsMigrated =*/ false);
+                            /* userRestrictionsMigrated =*/ false, /* remoteBugreportUri =*/ null,
+                            /* remoteBugreportHash =*/ null);
                     mDeviceOwnerUserId = UserHandle.USER_SYSTEM;
                 } else if (tag.equals(TAG_DEVICE_INITIALIZER)) {
                     // Deprecated tag
@@ -311,7 +334,7 @@
                                 profileOwnerComponentStr);
                         if (admin != null) {
                             profileOwnerInfo = new OwnerInfo(profileOwnerName, admin,
-                                /* userRestrictionsMigrated =*/ false);
+                                /* userRestrictionsMigrated =*/ false, null, null);
                         } else {
                             // This shouldn't happen but switch from package name -> component name
                             // might have written bad device owner files. b/17652534
@@ -321,7 +344,8 @@
                     }
                     if (profileOwnerInfo == null) {
                         profileOwnerInfo = new OwnerInfo(profileOwnerName, profileOwnerPackageName,
-                                /* userRestrictionsMigrated =*/ false);
+                                /* userRestrictionsMigrated =*/ false,
+                                /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/ null);
                     }
                     mProfileOwners.put(userId, profileOwnerInfo);
                 } else if (TAG_SYSTEM_UPDATE_POLICY.equals(tag)) {
@@ -579,19 +603,27 @@
         public final String packageName;
         public final ComponentName admin;
         public boolean userRestrictionsMigrated;
+        public String remoteBugreportUri;
+        public String remoteBugreportHash;
 
-        public OwnerInfo(String name, String packageName, boolean userRestrictionsMigrated) {
+        public OwnerInfo(String name, String packageName, boolean userRestrictionsMigrated,
+                String remoteBugreportUri, String remoteBugreportHash) {
             this.name = name;
             this.packageName = packageName;
             this.admin = new ComponentName(packageName, "");
             this.userRestrictionsMigrated = userRestrictionsMigrated;
+            this.remoteBugreportUri = remoteBugreportUri;
+            this.remoteBugreportHash = remoteBugreportHash;
         }
 
-        public OwnerInfo(String name, ComponentName admin, boolean userRestrictionsMigrated) {
+        public OwnerInfo(String name, ComponentName admin, boolean userRestrictionsMigrated,
+                String remoteBugreportUri, String remoteBugreportHash) {
             this.name = name;
             this.admin = admin;
             this.packageName = admin.getPackageName();
             this.userRestrictionsMigrated = userRestrictionsMigrated;
+            this.remoteBugreportUri = remoteBugreportUri;
+            this.remoteBugreportHash = remoteBugreportHash;
         }
 
         public void writeToXml(XmlSerializer out, String tag) throws IOException {
@@ -605,6 +637,12 @@
             }
             out.attribute(null, ATTR_USER_RESTRICTIONS_MIGRATED,
                     String.valueOf(userRestrictionsMigrated));
+            if (remoteBugreportUri != null) {
+                out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri);
+            }
+            if (remoteBugreportHash != null) {
+                out.attribute(null, ATTR_REMOTE_BUGREPORT_HASH, remoteBugreportHash);
+            }
             out.endTag(null, tag);
         }
 
@@ -617,12 +655,17 @@
                     parser.getAttributeValue(null, ATTR_USER_RESTRICTIONS_MIGRATED);
             final boolean userRestrictionsMigrated =
                     ("true".equals(userRestrictionsMigratedStr));
+            final String remoteBugreportUri = parser.getAttributeValue(null,
+                    ATTR_REMOTE_BUGREPORT_URI);
+            final String remoteBugreportHash = parser.getAttributeValue(null,
+                    ATTR_REMOTE_BUGREPORT_HASH);
 
             // Has component name?  If so, return [name, component]
             if (componentName != null) {
                 final ComponentName admin = ComponentName.unflattenFromString(componentName);
                 if (admin != null) {
-                    return new OwnerInfo(name, admin, userRestrictionsMigrated);
+                    return new OwnerInfo(name, admin, userRestrictionsMigrated,
+                            remoteBugreportUri, remoteBugreportHash);
                 } else {
                     // This shouldn't happen but switch from package name -> component name
                     // might have written bad device owner files. b/17652534
@@ -632,7 +675,8 @@
             }
 
             // Else, build with [name, package]
-            return new OwnerInfo(name, packageName, userRestrictionsMigrated);
+            return new OwnerInfo(name, packageName, userRestrictionsMigrated, remoteBugreportUri,
+                    remoteBugreportHash);
         }
 
         public void dump(String prefix, PrintWriter pw) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
new file mode 100644
index 0000000..3e1fbc7
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.text.format.DateUtils;
+
+import com.android.internal.R;
+
+/**
+ * Utilities class for the remote bugreport operation.
+ */
+class RemoteBugreportUtils {
+
+    static final int REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID = 678435657;
+    static final int REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID = 590907895;
+
+    static final long REMOTE_BUGREPORT_TIMEOUT_MILLIS = 10 * DateUtils.MINUTE_IN_MILLIS;
+
+    static final String CTL_STOP = "ctl.stop";
+    static final String REMOTE_BUGREPORT_SERVICE = "bugreportremote";
+
+    static final String ACTION_REMOTE_BUGREPORT_DISPATCH =
+            "android.intent.action.REMOTE_BUGREPORT_DISPATCH";
+    static final String ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED =
+            "com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED";
+    static final String ACTION_REMOTE_BUGREPORT_SHARING_DECLINED =
+            "com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED";
+    static final String EXTRA_REMOTE_BUGREPORT_HASH = "android.intent.extra.REMOTE_BUGREPORT_HASH";
+
+    static final String BUGREPORT_MIMETYPE = "application/vnd.android.bugreport";
+
+    static Notification buildRemoteBugreportConsentNotification(Context context) {
+        PendingIntent pendingIntentAccept = PendingIntent.getBroadcast(
+                context, REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
+                new Intent(ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED),
+                        PendingIntent.FLAG_CANCEL_CURRENT);
+        PendingIntent pendingIntentDecline = PendingIntent.getBroadcast(
+                context, REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
+                new Intent(ACTION_REMOTE_BUGREPORT_SHARING_DECLINED),
+                        PendingIntent.FLAG_CANCEL_CURRENT);
+
+        return new Notification.Builder(context)
+                .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+                .setContentTitle(context.getString(
+                        R.string.share_remote_bugreport_notification_title))
+                .setTicker(context.getString(R.string.share_remote_bugreport_notification_title))
+                .setContentText(context.getString(
+                        R.string.share_remote_bugreport_notification_message))
+                .setStyle(new Notification.BigTextStyle().bigText(context.getString(
+                        R.string.share_remote_bugreport_notification_message)))
+                .addAction(new Notification.Action.Builder(null /* icon */,
+                        context.getString(R.string.share_remote_bugreport_notification_decline),
+                        pendingIntentDecline).build())
+                .addAction(new Notification.Action.Builder(null /* icon */,
+                        context.getString(R.string.share_remote_bugreport_notification_accept),
+                        pendingIntentAccept).build())
+                .setOngoing(true)
+                .setLocalOnly(true)
+                .setColor(context.getColor(
+                        com.android.internal.R.color.system_notification_accent_color))
+                .setPriority(Notification.PRIORITY_MAX)
+                .setVibrate(new long[0])
+                .build();
+    }
+
+    static Notification buildRemoteBugreportInProgressNotification(Context context,
+            boolean canCancelBugreport) {
+        Notification.Builder builder = new Notification.Builder(context)
+                .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+                .setContentTitle(context.getString(
+                        R.string.remote_bugreport_progress_notification_title))
+                .setTicker(context.getString(
+                        R.string.remote_bugreport_progress_notification_title))
+                .setOngoing(true)
+                .setLocalOnly(true)
+                .setColor(context.getColor(
+                        com.android.internal.R.color.system_notification_accent_color))
+                .setPriority(Notification.PRIORITY_HIGH);
+
+        if (canCancelBugreport) {
+            PendingIntent pendingIntentCancel = PendingIntent.getBroadcast(context,
+                    REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID,
+                    new Intent(ACTION_REMOTE_BUGREPORT_SHARING_DECLINED),
+                    PendingIntent.FLAG_CANCEL_CURRENT);
+            String message = context.getString(
+                    R.string.remote_bugreport_progress_notification_message_can_cancel);
+            builder.setContentText(message)
+                    .setContentIntent(pendingIntentCancel)
+                    .setStyle(new Notification.BigTextStyle().bigText(message));
+        }
+        return builder.build();
+    }
+}
+
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 287b39c..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;
@@ -67,6 +70,7 @@
 import com.android.server.lights.LightsService;
 import com.android.server.media.MediaRouterService;
 import com.android.server.media.MediaSessionService;
+import com.android.server.media.MediaResourceMonitorService;
 import com.android.server.media.projection.MediaProjectionManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
 import com.android.server.net.NetworkStatsService;
@@ -94,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;
@@ -128,6 +134,8 @@
             "com.android.server.midi.MidiService$Lifecycle";
     private static final String WIFI_SERVICE_CLASS =
             "com.android.server.wifi.WifiService";
+    private static final String WIFI_NAN_SERVICE_CLASS =
+            "com.android.server.wifi.nan.WifiNanService";
     private static final String WIFI_P2P_SERVICE_CLASS =
             "com.android.server.wifi.p2p.WifiP2pService";
     private static final String ETHERNET_SERVICE_CLASS =
@@ -141,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
@@ -321,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);
         }
     }
@@ -632,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(
@@ -737,6 +780,11 @@
                 }
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+                if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_NAN)) {
+                    mSystemServiceManager.startService(WIFI_NAN_SERVICE_CLASS);
+                } else {
+                    Slog.i(TAG, "No Wi-Fi NAN Service (NAN support Not Present)");
+                }
                 mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
                 mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
                 mSystemServiceManager.startService(
@@ -1025,6 +1073,8 @@
                 mSystemServiceManager.startService(TvInputManagerService.class);
             }
 
+            mSystemServiceManager.startService(MediaResourceMonitorService.class);
+
             if (!disableNonCoreServices) {
                 traceBeginAndSlog("StartMediaRouterService");
                 try {
@@ -1041,7 +1091,7 @@
 
                 traceBeginAndSlog("StartBackgroundDexOptService");
                 try {
-                    BackgroundDexOptService.schedule(context, 0);
+                    BackgroundDexOptService.schedule(context);
                 } catch (Throwable e) {
                     reportWtf("starting BackgroundDexOptService", e);
                 }
diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java
index 0af1525..5ee4066 100644
--- a/services/print/java/com/android/server/print/RemotePrintService.java
+++ b/services/print/java/com/android/server/print/RemotePrintService.java
@@ -863,8 +863,7 @@
         }
 
         private void throwIfPrinterIdTampered(ComponentName serviceName, PrinterId printerId) {
-            if (printerId == null || printerId.getServiceName() == null
-                    || !printerId.getServiceName().equals(serviceName)) {
+            if (printerId == null || !printerId.getServiceName().equals(serviceName)) {
                 throw new IllegalArgumentException("Invalid printer id: " + printerId);
             }
         }
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index eed326e..3ae1072 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -27,7 +27,9 @@
     <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
     <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
-
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
+    <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
     <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
     <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
@@ -102,6 +104,8 @@
             </intent-filter>
         </receiver>
 
+        <service android:name="com.android.server.job.MockPriorityJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" />
     </application>
 
     <instrumentation
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/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
new file mode 100644
index 0000000..625fe77
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -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 com.android.server.am;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+
+import java.util.List;
+
+public class ActivityManagerTest extends AndroidTestCase {
+
+    IActivityManager service;
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        service = ActivityManagerNative.getDefault();
+    }
+
+    public void testTaskIdsForRunningUsers() throws RemoteException {
+        for(int userId : service.getRunningUserIds()) {
+            testTaskIdsForUser(userId);
+        }
+    }
+
+    private void testTaskIdsForUser(int userId) throws RemoteException {
+        List<ActivityManager.RecentTaskInfo> recentTasks = service.getRecentTasks(
+                100, 0, userId);
+        if(recentTasks != null) {
+            for(ActivityManager.RecentTaskInfo recentTask : recentTasks) {
+                int taskId = recentTask.persistentId;
+                assertEquals("The task id " + taskId + " should not belong to user " + userId,
+                        taskId / UserHandle.PER_USER_RANGE, userId);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 312b1b0..ae0a25e 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -179,7 +179,21 @@
                 loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS);
         // Assert late runtime was clamped to be now + period*2.
         assertTrue("Early runtime wasn't correctly clamped.",
-                loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS*2);
+                loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS * 2);
+    }
+
+    public void testPriorityPersisted() throws Exception {
+        JobInfo.Builder b = new Builder(92, mComponent)
+                .setOverrideDeadline(5000)
+                .setPriority(42)
+                .setPersisted(true);
+        final JobStatus js = new JobStatus(b.build(), SOME_UID);
+        mTaskStoreUnderTest.add(js);
+        Thread.sleep(IO_WAIT);
+        final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
+        mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+        JobStatus loaded = jobStatusSet.iterator().next();
+        assertEquals("Priority not correctly persisted.", 42, loaded.getPriority());
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/job/MockPriorityJobService.java b/services/tests/servicestests/src/com/android/server/job/MockPriorityJobService.java
new file mode 100644
index 0000000..3ea86f2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/job/MockPriorityJobService.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job;
+
+import android.annotation.TargetApi;
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+@TargetApi(24)
+public class MockPriorityJobService extends JobService {
+    private static final String TAG = "MockPriorityJobService";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.e(TAG, "Created test service.");
+    }
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        Log.i(TAG, "Test job executing: " + params.getJobId());
+        TestEnvironment.getTestEnvironment().executedEvents.add(
+                new TestEnvironment.Event(TestEnvironment.EVENT_START_JOB, params.getJobId()));
+        return true;  // Job not finished
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        Log.i(TAG, "Test job stop executing: " + params.getJobId());
+        int reason = params.getStopReason();
+        int event = TestEnvironment.EVENT_STOP_JOB;
+        Log.d(TAG, "stop reason: " + String.valueOf(reason));
+        if (reason == JobParameters.REASON_PREEMPT) {
+            event = TestEnvironment.EVENT_PREEMPT_JOB;
+            Log.d(TAG, "preempted " + String.valueOf(params.getJobId()));
+        }
+        TestEnvironment.getTestEnvironment().executedEvents
+                .add(new TestEnvironment.Event(event, params.getJobId()));
+        return false;  // Do not reschedule
+    }
+
+    public static class TestEnvironment {
+
+        public static final int EVENT_START_JOB = 0;
+        public static final int EVENT_PREEMPT_JOB = 1;
+        public static final int EVENT_STOP_JOB = 2;
+
+        private static TestEnvironment kTestEnvironment;
+
+        private ArrayList<Event> executedEvents = new ArrayList<Event>();
+
+        public static TestEnvironment getTestEnvironment() {
+            if (kTestEnvironment == null) {
+                kTestEnvironment = new TestEnvironment();
+            }
+            return kTestEnvironment;
+        }
+
+        public static class Event {
+            public int event;
+            public int jobId;
+
+            public Event() {
+            }
+
+            public Event(int event, int jobId) {
+                this.event = event;
+                this.jobId = jobId;
+            }
+
+            @Override
+            public boolean equals(Object other) {
+                if (other instanceof Event) {
+                    Event otherEvent = (Event) other;
+                    return otherEvent.event == event && otherEvent.jobId == jobId;
+                }
+                return false;
+            }
+        }
+
+        public void setUp() {
+            executedEvents.clear();
+        }
+
+        public ArrayList<Event> getExecutedEvents() {
+            return executedEvents;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/job/PrioritySchedulingTest.java b/services/tests/servicestests/src/com/android/server/job/PrioritySchedulingTest.java
new file mode 100644
index 0000000..63bccfa
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/job/PrioritySchedulingTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job;
+
+import android.annotation.TargetApi;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+import com.android.server.job.MockPriorityJobService.TestEnvironment;
+import com.android.server.job.MockPriorityJobService.TestEnvironment.Event;
+
+import java.util.ArrayList;
+
+@TargetApi(24)
+public class PrioritySchedulingTest extends AndroidTestCase {
+    /** Environment that notifies of JobScheduler callbacks. */
+    static TestEnvironment kTestEnvironment = TestEnvironment.getTestEnvironment();
+    /** Handle for the service which receives the execution callbacks from the JobScheduler. */
+    static ComponentName kJobServiceComponent;
+    JobScheduler mJobScheduler;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        kTestEnvironment.setUp();
+        kJobServiceComponent = new ComponentName(getContext(), MockPriorityJobService.class);
+        mJobScheduler = (JobScheduler) getContext().getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        mJobScheduler.cancelAll();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mJobScheduler.cancelAll();
+        super.tearDown();
+    }
+
+    public void testLowerPriorityJobPreempted() throws Exception {
+        JobInfo job1 = new JobInfo.Builder(111, kJobServiceComponent)
+                .setPriority(1)
+                .setOverrideDeadline(7000L)
+                .build();
+        JobInfo job2 = new JobInfo.Builder(222, kJobServiceComponent)
+                .setPriority(1)
+                .setOverrideDeadline(7000L)
+                .build();
+        JobInfo job3 = new JobInfo.Builder(333, kJobServiceComponent)
+                .setPriority(1)
+                .setOverrideDeadline(7000L)
+                .build();
+        JobInfo job4 = new JobInfo.Builder(444, kJobServiceComponent)
+                .setPriority(2)
+                .setMinimumLatency(2000L)
+                .setOverrideDeadline(7000L)
+                .build();
+        mJobScheduler.schedule(job1);
+        mJobScheduler.schedule(job2);
+        mJobScheduler.schedule(job3);
+        mJobScheduler.schedule(job4);
+        Thread.sleep(10000);  // Wait for job 4 to preempt one of the lower priority jobs
+
+        Event job4Execution = new Event(TestEnvironment.EVENT_START_JOB, 444);
+        ArrayList<Event> executedEvents = kTestEnvironment.getExecutedEvents();
+        boolean wasJob4Executed = executedEvents.contains(job4Execution);
+        boolean wasSomeJobPreempted = false;
+        for (Event event: executedEvents) {
+            if (event.event == TestEnvironment.EVENT_PREEMPT_JOB) {
+                wasSomeJobPreempted = true;
+                break;
+            }
+        }
+        assertTrue("No job was preempted.", wasSomeJobPreempted);
+        assertTrue("Lower priority jobs were not preempted.",  wasJob4Executed);
+    }
+
+    public void testHigherPriorityJobNotPreempted() throws Exception {
+        JobInfo job1 = new JobInfo.Builder(111, kJobServiceComponent)
+                .setPriority(2)
+                .setOverrideDeadline(7000L)
+                .build();
+        JobInfo job2 = new JobInfo.Builder(222, kJobServiceComponent)
+                .setPriority(2)
+                .setOverrideDeadline(7000L)
+                .build();
+        JobInfo job3 = new JobInfo.Builder(333, kJobServiceComponent)
+                .setPriority(2)
+                .setOverrideDeadline(7000L)
+                .build();
+        JobInfo job4 = new JobInfo.Builder(444, kJobServiceComponent)
+                .setPriority(1)
+                .setMinimumLatency(2000L)
+                .setOverrideDeadline(7000L)
+                .build();
+        mJobScheduler.schedule(job1);
+        mJobScheduler.schedule(job2);
+        mJobScheduler.schedule(job3);
+        mJobScheduler.schedule(job4);
+        Thread.sleep(10000);  // Wait for job 4 to preempt one of the higher priority jobs
+
+        Event job4Execution = new Event(TestEnvironment.EVENT_START_JOB, 444);
+        boolean wasJob4Executed = kTestEnvironment.getExecutedEvents().contains(job4Execution);
+        assertFalse("Higher priority job was preempted.", wasJob4Executed);
+    }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index e27441e..4253cd4 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -280,6 +280,11 @@
         mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
     }
 
+    @Override
+    public long getAppIdleRollingWindowDurationMillis() {
+        return mAppIdleWallclockThresholdMillis * 2;
+    }
+
     private void cleanUpRemovedUsersLocked() {
         final List<UserInfo> users = mUserManager.getUsers(true);
         if (users == null || users.size() == 0) {
@@ -548,7 +553,8 @@
             final int userCount = mUserState.size();
             for (int i = 0; i < userCount; i++) {
                 final UserUsageStatsService service = mUserState.valueAt(i);
-                service.onTimeChanged(expectedSystemTime, actualSystemTime, resetBeginIdleTime);
+                service.onTimeChanged(expectedSystemTime, actualSystemTime, mScreenOnTime,
+                        resetBeginIdleTime);
             }
             mRealTimeSnapshot = actualRealtime;
             mSystemTimeSnapshot = actualSystemTime;
@@ -1106,7 +1112,13 @@
      * Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}.
      */
     private class SettingsObserver extends ContentObserver {
-        private static final String KEY_IDLE_DURATION = "idle_duration";
+        /**
+         * This flag has been used to disable app idle on older builds with bug b/26355386.
+         */
+        @Deprecated
+        private static final String KEY_IDLE_DURATION_OLD = "idle_duration";
+
+        private static final String KEY_IDLE_DURATION = "idle_duration2";
         private static final String KEY_WALLCLOCK_THRESHOLD = "wallclock_threshold";
         private static final String KEY_PAROLE_INTERVAL = "parole_interval";
         private static final String KEY_PAROLE_DURATION = "parole_duration";
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 630367d..224faf4 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -73,6 +73,7 @@
 
     interface StatsUpdatedListener {
         void onStatsUpdated();
+        long getAppIdleRollingWindowDurationMillis();
     }
 
     UserUsageStatsService(Context context, int userId, File usageStatsDir,
@@ -134,12 +135,12 @@
             stat.updateConfigurationStats(null, stat.lastTimeSaved);
         }
 
+        refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime);
+
         if (mDatabase.isNewUpdate()) {
             initializeDefaultsForApps(currentTimeMillis, deviceUsageTime,
                     mDatabase.isFirstUpdate());
         }
-
-        refreshAppIdleRollingWindow(currentTimeMillis);
     }
 
     /**
@@ -161,19 +162,24 @@
                 for (IntervalStats stats : mCurrentStats) {
                     stats.update(packageName, currentTimeMillis, Event.SYSTEM_INTERACTION);
                     stats.updateBeginIdleTime(packageName, deviceUsageTime);
-                    mStatsChanged = true;
                 }
+
+                mAppIdleRollingWindow.update(packageName, currentTimeMillis,
+                        Event.SYSTEM_INTERACTION);
+                mAppIdleRollingWindow.updateBeginIdleTime(packageName, deviceUsageTime);
+                mStatsChanged = true;
             }
         }
         // Persist the new OTA-related access stats.
         persistActiveStats();
     }
 
-    void onTimeChanged(long oldTime, long newTime, boolean resetBeginIdleTime) {
+    void onTimeChanged(long oldTime, long newTime, long deviceUsageTime,
+                       boolean resetBeginIdleTime) {
         persistActiveStats();
         mDatabase.onTimeChanged(newTime - oldTime);
         loadActiveStats(newTime, resetBeginIdleTime);
-        refreshAppIdleRollingWindow(newTime);
+        refreshAppIdleRollingWindow(newTime, deviceUsageTime);
     }
 
     void reportEvent(UsageEvents.Event event, long deviceUsageTime) {
@@ -185,7 +191,7 @@
 
         if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
             // Need to rollover
-            rolloverStats(event.mTimeStamp);
+            rolloverStats(event.mTimeStamp, deviceUsageTime);
         }
 
         final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
@@ -429,7 +435,7 @@
         }
     }
 
-    private void rolloverStats(final long currentTimeMillis) {
+    private void rolloverStats(final long currentTimeMillis, final long deviceUsageTime) {
         final long startTime = SystemClock.elapsedRealtime();
         Slog.i(TAG, mLogPrefix + "Rolling over usage stats");
 
@@ -470,7 +476,7 @@
         }
         persistActiveStats();
 
-        refreshAppIdleRollingWindow(currentTimeMillis);
+        refreshAppIdleRollingWindow(currentTimeMillis, deviceUsageTime);
 
         final long totalTime = SystemClock.elapsedRealtime() - startTime;
         Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime
@@ -528,44 +534,30 @@
                 mDailyExpiryDate.getTimeInMillis() + ")");
     }
 
-    private static void mergePackageStats(IntervalStats dst, IntervalStats src) {
+    private static void mergePackageStats(IntervalStats dst, IntervalStats src,
+                                          final long deviceUsageTime) {
         dst.endTime = Math.max(dst.endTime, src.endTime);
 
         final int srcPackageCount = src.packageStats.size();
         for (int i = 0; i < srcPackageCount; i++) {
             final String packageName = src.packageStats.keyAt(i);
             final UsageStats srcStats = src.packageStats.valueAt(i);
-            final UsageStats dstStats = dst.packageStats.get(packageName);
+            UsageStats dstStats = dst.packageStats.get(packageName);
             if (dstStats == null) {
-                dst.packageStats.put(packageName, new UsageStats(srcStats));
+                dstStats = new UsageStats(srcStats);
+                dst.packageStats.put(packageName, dstStats);
             } else {
                 dstStats.add(src.packageStats.valueAt(i));
             }
+
+            // App idle times can not begin in the future. This happens if we had a time change.
+            if (dstStats.mBeginIdleTime > deviceUsageTime) {
+                dstStats.mBeginIdleTime = deviceUsageTime;
+            }
         }
     }
 
     /**
-     * Merges all the stats into the first element of the resulting list.
-     */
-    private static final StatCombiner<IntervalStats> sPackageStatsMerger =
-            new StatCombiner<IntervalStats>() {
-        @Override
-        public void combine(IntervalStats stats, boolean mutable,
-                            List<IntervalStats> accumulatedResult) {
-            IntervalStats accum;
-            if (accumulatedResult.isEmpty()) {
-                accum = new IntervalStats();
-                accum.beginTime = stats.beginTime;
-                accumulatedResult.add(accum);
-            } else {
-                accum = accumulatedResult.get(0);
-            }
-
-            mergePackageStats(accum, stats);
-        }
-    };
-
-    /**
      * App idle operates on a rolling window of time. When we roll over time, we end up with a
      * period of time where in-memory stats are empty and we don't hit the disk for older stats
      * for performance reasons. Suddenly all apps will become idle.
@@ -575,16 +567,33 @@
      *
      * @param currentTimeMillis
      */
-    void refreshAppIdleRollingWindow(long currentTimeMillis) {
+    void refreshAppIdleRollingWindow(final long currentTimeMillis, final long deviceUsageTime) {
         // Start the rolling window for AppIdle requests.
+        final long startRangeMillis = currentTimeMillis -
+                mListener.getAppIdleRollingWindowDurationMillis();
+
         List<IntervalStats> stats = mDatabase.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
-                currentTimeMillis - (1000 * 60 * 60 * 24 * 2), currentTimeMillis,
-                sPackageStatsMerger);
+                startRangeMillis, currentTimeMillis, new StatCombiner<IntervalStats>() {
+                    @Override
+                    public void combine(IntervalStats stats, boolean mutable,
+                                        List<IntervalStats> accumulatedResult) {
+                        IntervalStats accum;
+                        if (accumulatedResult.isEmpty()) {
+                            accum = new IntervalStats();
+                            accum.beginTime = stats.beginTime;
+                            accumulatedResult.add(accum);
+                        } else {
+                            accum = accumulatedResult.get(0);
+                        }
+
+                        mergePackageStats(accum, stats, deviceUsageTime);
+                    }
+                });
 
         if (stats == null || stats.isEmpty()) {
             mAppIdleRollingWindow = new IntervalStats();
             mergePackageStats(mAppIdleRollingWindow,
-                    mCurrentStats[UsageStatsManager.INTERVAL_YEARLY]);
+                    mCurrentStats[UsageStatsManager.INTERVAL_YEARLY], deviceUsageTime);
         } else {
             mAppIdleRollingWindow = stats.get(0);
         }
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index a915d37..a5e8fe1 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.Process;
 import android.provider.Settings;
 import android.text.TextUtils;
 
@@ -150,12 +151,13 @@
      *
      * @hide
      **/
-    public static List<String> getInstalledDialerApplications(Context context) {
+    public static List<String> getInstalledDialerApplications(Context context, int userId) {
         PackageManager packageManager = context.getPackageManager();
 
         // Get the list of apps registered for the DIAL intent with empty scheme
         Intent intent = new Intent(Intent.ACTION_DIAL);
-        List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
+        List<ResolveInfo> resolveInfoList =
+                packageManager.queryIntentActivitiesAsUser(intent, 0, userId);
 
         List<String> packageNames = new ArrayList<>();
 
@@ -171,6 +173,10 @@
         return filterByIntent(context, packageNames, dialIntentWithTelScheme);
     }
 
+    public static List<String> getInstalledDialerApplications(Context context) {
+        return getInstalledDialerApplications(context, Process.myUserHandle().getIdentifier());
+    }
+
     /**
      * Determines if the package name belongs to the user-selected default dialer or the preloaded
      * system dialer, and thus should be allowed to perform certain privileged operations.
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.aidl b/telecomm/java/android/telecom/ParcelableCallAnalytics.aidl
new file mode 100644
index 0000000..b7e78d1
--- /dev/null
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom;
+
+/**
+ * {@hide}
+ */
+parcelable ParcelableCallAnalytics;
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
new file mode 100644
index 0000000..e7c9672
--- /dev/null
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -0,0 +1,184 @@
+/*
+ * 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.telecom;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+@SystemApi
+public class ParcelableCallAnalytics implements Parcelable {
+    public static final int CALLTYPE_UNKNOWN = 0;
+    public static final int CALLTYPE_INCOMING = 1;
+    public static final int CALLTYPE_OUTGOING = 2;
+
+    // Constants for call technology
+    public static final int CDMA_PHONE = 0x1;
+    public static final int GSM_PHONE = 0x2;
+    public static final int IMS_PHONE = 0x4;
+    public static final int SIP_PHONE = 0x8;
+    public static final int THIRD_PARTY_PHONE = 0x10;
+
+    public static final long MILLIS_IN_5_MINUTES = 1000 * 60 * 5;
+    public static final long MILLIS_IN_1_SECOND = 1000;
+
+    public static final int STILL_CONNECTED = -1;
+
+    public static final Parcelable.Creator<ParcelableCallAnalytics> CREATOR =
+            new Parcelable.Creator<ParcelableCallAnalytics> () {
+
+                @Override
+                public ParcelableCallAnalytics createFromParcel(Parcel in) {
+                    return new ParcelableCallAnalytics(in);
+                }
+
+                @Override
+                public ParcelableCallAnalytics[] newArray(int size) {
+                    return new ParcelableCallAnalytics[size];
+                }
+            };
+
+    // The start time of the call in milliseconds since Jan. 1, 1970, rounded to the nearest
+    // 5 minute increment.
+    private final long startTimeMillis;
+
+    // The duration of the call, in milliseconds.
+    private final long callDurationMillis;
+
+    // ONE OF calltype_unknown, calltype_incoming, or calltype_outgoing
+    private final int callType;
+
+    // true if the call came in while another call was in progress or if the user dialed this call
+    // while in the middle of another call.
+    private final boolean isAdditionalCall;
+
+    // true if the call was interrupted by an incoming or outgoing call.
+    private final boolean isInterrupted;
+
+    // bitmask denoting which technologies a call used.
+    private final int callTechnologies;
+
+    // Any of the DisconnectCause codes, or STILL_CONNECTED.
+    private final int callTerminationCode;
+
+    // Whether the call is an emergency call
+    private final boolean isEmergencyCall;
+
+    // The package name of the connection service that this call used.
+    private final String connectionService;
+
+    // Whether the call object was created from an existing connection.
+    private final boolean isCreatedFromExistingConnection;
+
+    public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
+            boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
+            int callTerminationCode, boolean isEmergencyCall, String connectionService,
+            boolean isCreatedFromExistingConnection) {
+        this.startTimeMillis = startTimeMillis;
+        this.callDurationMillis = callDurationMillis;
+        this.callType = callType;
+        this.isAdditionalCall = isAdditionalCall;
+        this.isInterrupted = isInterrupted;
+        this.callTechnologies = callTechnologies;
+        this.callTerminationCode = callTerminationCode;
+        this.isEmergencyCall = isEmergencyCall;
+        this.connectionService = connectionService;
+        this.isCreatedFromExistingConnection = isCreatedFromExistingConnection;
+    }
+
+    public ParcelableCallAnalytics(Parcel in) {
+        startTimeMillis = in.readLong();
+        callDurationMillis = in.readLong();
+        callType = in.readInt();
+        isAdditionalCall = readByteAsBoolean(in);
+        isInterrupted = readByteAsBoolean(in);
+        callTechnologies = in.readInt();
+        callTerminationCode = in.readInt();
+        isEmergencyCall = readByteAsBoolean(in);
+        connectionService = in.readString();
+        isCreatedFromExistingConnection = readByteAsBoolean(in);
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(startTimeMillis);
+        out.writeLong(callDurationMillis);
+        out.writeInt(callType);
+        writeBooleanAsByte(out, isAdditionalCall);
+        writeBooleanAsByte(out, isInterrupted);
+        out.writeInt(callTechnologies);
+        out.writeInt(callTerminationCode);
+        writeBooleanAsByte(out, isEmergencyCall);
+        out.writeString(connectionService);
+        writeBooleanAsByte(out, isCreatedFromExistingConnection);
+    }
+
+    public long getStartTimeMillis() {
+        return startTimeMillis;
+    }
+
+    public long getCallDurationMillis() {
+        return callDurationMillis;
+    }
+
+    public int getCallType() {
+        return callType;
+    }
+
+    public boolean isAdditionalCall() {
+        return isAdditionalCall;
+    }
+
+    public boolean isInterrupted() {
+        return isInterrupted;
+    }
+
+    public int getCallTechnologies() {
+        return callTechnologies;
+    }
+
+    public int getCallTerminationCode() {
+        return callTerminationCode;
+    }
+
+    public boolean isEmergencyCall() {
+        return isEmergencyCall;
+    }
+
+    public String getConnectionService() {
+        return connectionService;
+    }
+
+    public boolean isCreatedFromExistingConnection() {
+        return isCreatedFromExistingConnection;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    private static void writeBooleanAsByte(Parcel out, boolean b) {
+        out.writeByte((byte) (b ? 1 : 0));
+    }
+
+    private static boolean readByteAsBoolean(Parcel in) {
+        return (in.readByte() == 1);
+    }
+}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 9eb1665..d45b26f 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -14,6 +14,7 @@
 
 package android.telecom;
 
+import android.Manifest;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
@@ -1377,6 +1378,27 @@
         }
     }
 
+    /**
+     * Dumps telecom analytics for uploading.
+     *
+     * @return
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.DUMP)
+    public List<ParcelableCallAnalytics> dumpAnalytics() {
+        ITelecomService service = getTelecomService();
+        List<ParcelableCallAnalytics> result = null;
+        if (service != null) {
+            try {
+                result = service.dumpCallAnalytics();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error dumping call analytics", e);
+            }
+        }
+        return result;
+    }
+
     private ITelecomService getTelecomService() {
         if (mTelecomServiceOverride != null) {
             return mTelecomServiceOverride;
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 856e210..af36b3e 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -17,6 +17,7 @@
 package com.android.internal.telecom;
 
 import android.content.ComponentName;
+import android.telecom.ParcelableCallAnalytics;
 import android.telecom.PhoneAccountHandle;
 import android.net.Uri;
 import android.os.Bundle;
@@ -143,6 +144,11 @@
      */
     String getSystemDialerPackage();
 
+    /**
+    * @see TelecomServiceImpl#dumpCallAnalytics
+    */
+    List<ParcelableCallAnalytics> dumpCallAnalytics();
+
     //
     // Internal system apis relating to call management.
     //
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 80c5b1e..320d274 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -81,7 +81,6 @@
      * Flag to require or skip entitlement checks.
      * If true, entitlement checks will be executed if device has been configured for it,
      * If false, entitlement checks will be skipped.
-     * @hide
      */
     public static final String
             KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
@@ -269,7 +268,6 @@
 
     /**
      * Flag specifying whether Generic Bootstrapping Architecture capable SIM is required for IMS.
-     * @hide
      */
     public static final String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL
             = "carrier_ims_gba_required_bool";
@@ -277,7 +275,6 @@
     /**
      * Flag specifying whether IMS instant lettering is available for the carrier.  {@code True} if
      * instant lettering is available for the carrier, {@code false} otherwise.
-     * @hide
      */
     public static final String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL =
             "carrier_instant_lettering_available_bool";
@@ -294,7 +291,6 @@
      * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines the list of characters
      * which may not be contained in messages.  Should be specified as a regular expression suitable
      * for use with {@link String#matches(String)}.
-     * @hide
      */
     public static final String KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING =
             "carrier_instant_lettering_invalid_chars_string";
@@ -305,7 +301,6 @@
      * must be escaped with a backslash '\' character.  Should be specified as a string containing
      * the characters to be escaped.  For example to escape quote and backslash the string would be
      * a quote and a backslash.
-     * @hide
      */
     public static final String KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING =
             "carrier_instant_lettering_escaped_chars_string";
@@ -319,7 +314,6 @@
      * towards the messages size limit as a single bye.  If a character encoding is specified, the
      * message size limit will be based on the number of bytes in the message per the specified
      * encoding.
-     * @hide
      */
     public static final String KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING =
             "carrier_instant_lettering_encoding_string";
@@ -330,7 +324,6 @@
      * in the InCall UI to ensure the user cannot enter more characters than allowed by the carrier.
      * See also {@link #KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING} for more information on how
      * the length of the message is calculated.
-     * @hide
      */
     public static final String KEY_CARRIER_INSTANT_LETTERING_LENGTH_LIMIT_INT =
             "carrier_instant_lettering_length_limit_int";
@@ -353,7 +346,6 @@
     /**
      * The default flag specifying whether ETWS/CMAS test setting is forcibly disabled in
      * Settings->More->Emergency broadcasts menu even though developer options is turned on.
-     * @hide
      */
     public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL =
             "carrier_force_disable_etws_cmas_test_bool";
@@ -361,11 +353,38 @@
     /**
      * The default flag specifying whether "Turn on Notifications" option will be always shown in
      * Settings->More->Emergency broadcasts menu regardless developer options is turned on or not.
-     * @hide
      */
     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. */
 
     /**
@@ -398,27 +417,23 @@
     /**
      * Flag specifying whether an additional (client initiated) intent needs to be sent on System
      * update
-     * @hide
      */
     public static final String KEY_CI_ACTION_ON_SYS_UPDATE_BOOL = "ci_action_on_sys_update_bool";
 
     /**
      * Intent to be sent for the additional action on System update
-     * @hide
      */
     public static final String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING =
             "ci_action_on_sys_update_intent_string";
 
     /**
      * Extra to be included in the intent sent for additional action on System update
-     * @hide
      */
     public static final String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING =
             "ci_action_on_sys_update_extra_string";
 
     /**
      * Value of extra included in intent sent for additional action on System update
-     * @hide
      */
     public static final String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING =
             "ci_action_on_sys_update_extra_val_string";
@@ -427,7 +442,6 @@
      * Specifies the amount of gap to be added in millis between postdial DTMF tones. When a
      * non-zero value is specified, the UE shall wait for the specified amount of time before it
      * sends out successive DTMF tones on the network.
-     * @hide
      */
     public static final String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
 
@@ -435,7 +449,6 @@
      * Specifies the amount of gap to be added in millis between DTMF tones. When a non-zero value
      * is specified, the UE shall wait for the specified amount of time before it sends out
      * successive DTMF tones on the network.
-     * @hide
      */
     public static final String KEY_IMS_DTMF_TONE_DELAY_INT = "ims_dtmf_tone_delay_int";
 
@@ -443,32 +456,27 @@
      * Specifies the amount of gap to be added in millis between postdial DTMF tones. When a
      * non-zero value is specified, the UE shall wait for the specified amount of time before it
      * sends out successive DTMF tones on the network.
-     * @hide
      */
     public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
 
     /**
      * Determines whether conference calls are supported by a carrier.  When {@code true},
      * conference calling is supported, {@code false otherwise}.
-     * @hide
      */
     public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
 
     /**
      * Determine whether user can toggle Enhanced 4G LTE Mode in Settings.
-     * @hide
      */
     public static final String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
 
     /**
      * Determine whether IMS apn can be shown.
-     * @hide
      */
     public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
 
     /**
      * Determine whether preferred network type can be shown.
-     * @hide
      */
     public static final String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
 
@@ -491,10 +499,16 @@
 
     /**
      * Allow user to add APNs
-     * @hide
      */
     public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
 
+    /**
+     * Boolean indicating if intent for emergency call state changes should be broadcast
+     * @hide
+     */
+    public static final String KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL =
+            "broadcast_emergency_call_state_changes_bool";
+
     // These variables are used by the MMS service and exposed through another API, {@link
     // SmsManager}. The variable names and string values are copied from there.
     public static final String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
@@ -533,7 +547,6 @@
      * Determines whether the carrier supports making non-emergency phone calls while the phone is
      * in emergency callback mode.  Default value is {@code true}, meaning that non-emergency calls
      * are allowed in emergency callback mode.
-     * @hide
      */
     public static final String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL =
             "allow_non_emergency_calls_in_ecm_bool";
@@ -542,8 +555,6 @@
      * Flag indicating whether to allow carrier video calls to emergency numbers.
      * When {@code true}, video calls to emergency numbers will be allowed.  When {@code false},
      * video calls to emergency numbers will be initiated as audio-only calls instead.
-     *
-     * @hide
      */
     @SystemApi
     public static final String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS =
@@ -555,8 +566,6 @@
      * to pause transmission of video when the In-Call app is sent to the background.
      * When {@code false}, video pause signaling is not supported.  {@code True} by default unless
      * a carrier configuration overrides the default.
-     *
-     * @hide
      */
     @SystemApi
     public static final String BOOL_ALLOW_VIDEO_PAUSE =
@@ -573,8 +582,6 @@
      * via {@link android.telecom.PhoneAccount#CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE}
      * and can choose to hide or show the video calling icon based on whether a contact supports
      * video.
-     *
-     * @hide
      */
     @SystemApi
     public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool";
@@ -638,7 +645,15 @@
         sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, "");
         sDefaults.putBoolean(KEY_CSP_ENABLED_BOOL, false);
         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 913cb18..7eaa6a6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -296,7 +296,7 @@
     /**
      * @hide
      */
-    public static final boolean EMERGENCY_ASSISTANCE_ENABLED = false;
+    public static final boolean EMERGENCY_ASSISTANCE_ENABLED = true;
 
     /**
      * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
@@ -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);
@@ -3998,19 +4001,6 @@
 
     /** @hide */
     @SystemApi
-    public boolean isSimPinEnabled() {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null)
-                return telephony.isSimPinEnabled(getOpPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#isSimPinEnabled", e);
-        }
-        return false;
-    }
-
-    /** @hide */
-    @SystemApi
     public boolean supplyPin(String pin) {
         try {
             ITelephony telephony = getITelephony();
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 59a8a67..b9d7297 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -53,6 +53,9 @@
     private static final String TAG = "CallerInfo";
     private static final boolean VDBG = Rlog.isLoggable(TAG, Log.VERBOSE);
 
+    public static final long USER_TYPE_CURRENT = 0;
+    public static final long USER_TYPE_WORK = 1;
+
     /**
      * Please note that, any one of these member variables can be null,
      * and any accesses to them should be prepared to handle such a case.
@@ -103,6 +106,8 @@
     public Uri contactRefUri;
     public String lookupKey;
 
+    public long userType;
+
     /**
      * Contact display photo URI.  If a contact has no display photo but a thumbnail, it'll be
      * the thumbnail URI instead.
@@ -154,6 +159,7 @@
         // TODO: Move all the basic initialization here?
         mIsEmergency = false;
         mIsVoiceMail = false;
+        userType = USER_TYPE_CURRENT;
     }
 
     /**
@@ -173,6 +179,7 @@
         info.cachedPhoto = null;
         info.isCachedPhotoCurrent = false;
         info.contactExists = false;
+        info.userType = USER_TYPE_CURRENT;
 
         if (VDBG) Rlog.v(TAG, "getCallerInfo() based on cursor...");
 
@@ -225,6 +232,9 @@
                             Rlog.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero);
                         }
                     }
+                    if (Contacts.isEnterpriseContactId(contactId)) {
+                        info.userType = USER_TYPE_WORK;
+                    }
                 } else {
                     // No valid columnIndex, so we can't look up person_id.
                     Rlog.w(TAG, "Couldn't find contact_id column for " + contactRef);
@@ -628,6 +638,7 @@
     /**
      * @return a string debug representation of this instance.
      */
+    @Override
     public String toString() {
         // Warning: never check in this file with VERBOSE_DEBUG = true
         // because that will result in PII in the system log.
@@ -658,6 +669,7 @@
                     .append("\nemergency: " + mIsEmergency)
                     .append("\nvoicemail " + mIsVoiceMail)
                     .append("\ncontactExists " + contactExists)
+                    .append("\nuserType " + userType)
                     .append(" }")
                     .toString();
         } else {
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/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d1badc9..62f294c 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -182,13 +182,6 @@
     boolean isRadioOnForSubscriber(int subId, String callingPackage);
 
     /**
-     * Check if the SIM pin lock is enabled.
-     * @return true if the SIM pin lock is enabled.
-     * @param callingPackage The package making the call.
-     */
-    boolean isSimPinEnabled(String callingPackage);
-
-    /**
      * Supply a pin to unlock the SIM.  Blocks until a result is determined.
      * @param pin The pin to check.
      * @return whether the operation was a success.
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl b/telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl
new file mode 100644
index 0000000..5dffa28
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ITelephonyDebug.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.os.Bundle;
+
+
+/**
+ * Interface used to interact with the Telephony debug service.
+ *
+ * {@hide}
+ */
+interface ITelephonyDebug {
+
+    /**
+     * Write telephony event
+     * @param timestamp returned by System.currentTimeMillis()
+     * @param phoneId for which event is written
+     * @param tag constant defined in TelephonyEventLog
+     * @param param1 optional
+     * @param param2 optional
+     * @param data optional
+     */
+    void writeEvent(long timestamp, int phoneId, int tag, int param1, int param2, in Bundle data);
+}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index a183de5..ecd89ed 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -35,17 +35,17 @@
         IDLE, RINGING, OFFHOOK;
     };
 
-   /**
-     * The state of a data connection.
-     * <ul>
-     * <li>CONNECTED = IP traffic should be available</li>
-     * <li>CONNECTING = Currently setting up data connection</li>
-     * <li>DISCONNECTED = IP not available</li>
-     * <li>SUSPENDED = connection is created but IP traffic is
-     *                 temperately not available. i.e. voice call is in place
-     *                 in 2G network</li>
-     * </ul>
-     */
+    /**
+      * The state of a data connection.
+      * <ul>
+      * <li>CONNECTED = IP traffic should be available</li>
+      * <li>CONNECTING = Currently setting up data connection</li>
+      * <li>DISCONNECTED = IP not available</li>
+      * <li>SUSPENDED = connection is created but IP traffic is
+      *                 temperately not available. i.e. voice call is in place
+      *                 in 2G network</li>
+      * </ul>
+      */
     public enum DataState {
         CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED;
     };
@@ -89,6 +89,7 @@
     public static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
     public static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming";
     public static final String PHONE_IN_ECM_STATE = "phoneinECMState";
+    public static final String PHONE_IN_EMERGENCY_CALL = "phoneInEmergencyCall";
 
     public static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
 
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index d2e4de3..c70f8cf 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -75,6 +75,7 @@
      */
     public static final String ACTION_RADIO_TECHNOLOGY_CHANGED
             = "android.intent.action.RADIO_TECHNOLOGY";
+
     /**
      * <p>Broadcast Action: The emergency callback mode is changed.
      * <ul>
@@ -94,6 +95,28 @@
      */
     public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
             = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED";
+
+    /**
+     * <p>Broadcast Action: The emergency call state is changed.
+     * <ul>
+     *   <li><em>phoneInEmergencyCall</em> - A boolean value, true if phone in emergency call,
+     *   false otherwise</li>
+     * </ul>
+     * <p class="note">
+     * You can <em>not</em> receive this through components declared
+     * in manifests, only by explicitly registering for it with
+     * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,
+     * android.content.IntentFilter) Context.registerReceiver()}.
+     *
+     * <p class="note">
+     * Requires no permission.
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     */
+    public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED
+            = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED";
+
     /**
      * Broadcast Action: The phone's signal strength has changed. The intent will have the
      * following extra values:</p>
diff --git a/tests/FeatureSplit/base/AndroidManifest.xml b/tests/FeatureSplit/base/AndroidManifest.xml
index 989e802..e82b3b9 100644
--- a/tests/FeatureSplit/base/AndroidManifest.xml
+++ b/tests/FeatureSplit/base/AndroidManifest.xml
@@ -16,7 +16,15 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.test.split.feature">
-    <application android:label="@string/app_title"
-        android:hasCode="false">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+    <application android:label="@string/app_title">
+        <activity android:name=".ActivityMain" android:label="Feature Base">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
diff --git a/tests/FeatureSplit/base/res/layout/main.xml b/tests/FeatureSplit/base/res/layout/main.xml
new file mode 100644
index 0000000..f01b920
--- /dev/null
+++ b/tests/FeatureSplit/base/res/layout/main.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:padding="16dp">
+    <TextView android:id="@+id/text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerInParent="true"
+        android:textAppearance="?android:textAppearanceLarge" />
+</RelativeLayout>
diff --git a/tests/FeatureSplit/base/res/values/values.xml b/tests/FeatureSplit/base/res/values/values.xml
index 564d301..854a8bb 100644
--- a/tests/FeatureSplit/base/res/values/values.xml
+++ b/tests/FeatureSplit/base/res/values/values.xml
@@ -16,6 +16,7 @@
 
 <resources>
     <string name="app_title">FeatureSplit APK</string>
+    <string name="base">Base</string>
 
     <item type="id" name="test_id"/>
     <integer name="test_integer">100</integer>
diff --git a/tests/FeatureSplit/base/src/com/android/test/split/feature/ActivityMain.java b/tests/FeatureSplit/base/src/com/android/test/split/feature/ActivityMain.java
new file mode 100644
index 0000000..6cca7c3
--- /dev/null
+++ b/tests/FeatureSplit/base/src/com/android/test/split/feature/ActivityMain.java
@@ -0,0 +1,31 @@
+/*
+ * 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.test.split.feature;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class ActivityMain extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+        ((TextView) findViewById(R.id.text)).setText(R.string.base);
+    }
+}
+
diff --git a/tests/FeatureSplit/feature1/Android.mk b/tests/FeatureSplit/feature1/Android.mk
index adfb575..aa222dd 100644
--- a/tests/FeatureSplit/feature1/Android.mk
+++ b/tests/FeatureSplit/feature1/Android.mk
@@ -22,10 +22,12 @@
 LOCAL_MODULE_TAGS := tests
 
 featureOf := FeatureSplitBase
+
+LOCAL_APK_LIBRARIES := $(featureOf)
 featureOfApk := $(call intermediates-dir-for,APPS,$(featureOf))/package.apk
 localRStamp := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src/R.stamp
 $(localRStamp): $(featureOfApk)
 
-LOCAL_AAPT_FLAGS := --feature-of $(featureOfApk)
+LOCAL_AAPT_FLAGS := --feature-of $(featureOfApk) --custom-package com.android.test.split.feature.one
 
 include $(BUILD_PACKAGE)
diff --git a/tests/FeatureSplit/feature1/AndroidManifest.xml b/tests/FeatureSplit/feature1/AndroidManifest.xml
index 2aadc6d..42619b6 100644
--- a/tests/FeatureSplit/feature1/AndroidManifest.xml
+++ b/tests/FeatureSplit/feature1/AndroidManifest.xml
@@ -17,5 +17,15 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.test.split.feature"
     featureName="feature1">
-    <application android:hasCode="false" />
+
+    <uses-sdk android:minSdkVersion="21" />
+
+    <application>
+        <activity android:name=".one.One" android:label="Feature One">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
 </manifest>
diff --git a/tests/FeatureSplit/feature1/res/values/values.xml b/tests/FeatureSplit/feature1/res/values/values.xml
index 70eb56a..10dbd97 100644
--- a/tests/FeatureSplit/feature1/res/values/values.xml
+++ b/tests/FeatureSplit/feature1/res/values/values.xml
@@ -15,6 +15,7 @@
 -->
 
 <resources>
+    <string name="feature_string">Feature1</string>
     <item type="id" name="test_id2"/>
     <integer name="test_integer2">200</integer>
     <color name="test_color2">#00ff00</color>
diff --git a/tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java b/tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java
new file mode 100644
index 0000000..def1339
--- /dev/null
+++ b/tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java
@@ -0,0 +1,31 @@
+/*
+ * 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.test.split.feature.one;
+
+import com.android.test.split.feature.ActivityMain;
+
+import android.widget.TextView;
+import android.os.Bundle;
+
+public class One extends ActivityMain {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ((TextView) findViewById(com.android.test.split.feature.R.id.text))
+                .setText(R.string.feature_string);
+    }
+}
diff --git a/tests/FeatureSplit/feature2/Android.mk b/tests/FeatureSplit/feature2/Android.mk
index e69cbe8..1a0322b 100644
--- a/tests/FeatureSplit/feature2/Android.mk
+++ b/tests/FeatureSplit/feature2/Android.mk
@@ -24,6 +24,8 @@
 featureOf := FeatureSplitBase
 featureAfter := FeatureSplit1
 
+LOCAL_APK_LIBRARIES := $(featureOf)
+
 featureOfApk := $(call intermediates-dir-for,APPS,$(featureOf))/package.apk
 featureAfterApk := $(call intermediates-dir-for,APPS,$(featureAfter))/package.apk
 localRStamp := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src/R.stamp
@@ -31,5 +33,6 @@
 
 LOCAL_AAPT_FLAGS := --feature-of $(featureOfApk)
 LOCAL_AAPT_FLAGS += --feature-after $(featureAfterApk)
+LOCAL_AAPT_FLAGS += --custom-package com.android.test.split.feature.two
 
 include $(BUILD_PACKAGE)
diff --git a/tests/FeatureSplit/feature2/AndroidManifest.xml b/tests/FeatureSplit/feature2/AndroidManifest.xml
index d139900..b50044a 100644
--- a/tests/FeatureSplit/feature2/AndroidManifest.xml
+++ b/tests/FeatureSplit/feature2/AndroidManifest.xml
@@ -17,5 +17,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.test.split.feature"
     featureName="feature2">
+
+    <uses-sdk android:minSdkVersion="21" />
+
     <application android:hasCode="false"/>
 </manifest>
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 576f076..4d9ba6c 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -2119,7 +2119,7 @@
                 indentStr);
     }
 
-    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
 }
 
 static status_t writeResourceLoadedCallback(
diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
index 64353de..13f8b3b 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/tools/aapt2/ConfigDescription.cpp
@@ -30,6 +30,11 @@
 
 static const char* kWildcardName = "any";
 
+const ConfigDescription& ConfigDescription::defaultConfig() {
+    static ConfigDescription config = {};
+    return config;
+}
+
 static bool parseMcc(const char* name, ResTable_config* out) {
     if (strcmp(name, kWildcardName) == 0) {
         if (out) out->mcc = 0;
diff --git a/tools/aapt2/ConfigDescription.h b/tools/aapt2/ConfigDescription.h
index 4af089d..5749816 100644
--- a/tools/aapt2/ConfigDescription.h
+++ b/tools/aapt2/ConfigDescription.h
@@ -29,6 +29,11 @@
  * initialization and comparison methods.
  */
 struct ConfigDescription : public android::ResTable_config {
+    /**
+     * Returns an immutable default config.
+     */
+    static const ConfigDescription& defaultConfig();
+
     /*
      * Parse a string of the form 'fr-sw600dp-land' and fill in the
      * given ResTable_config with resulting configuration parameters.
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 5fce2c1..b4e75f9 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -210,4 +210,19 @@
     std::cout << "}" << std::endl;
 }
 
+void Debug::dumpHex(const void* data, size_t len) {
+    const uint8_t* d = (const uint8_t*) data;
+    for (size_t i = 0; i < len; i++) {
+        std::cerr << std::hex << std::setfill('0') << std::setw(2) << (uint32_t) d[i] << " ";
+        if (i % 8 == 7) {
+            std::cerr << "\n";
+        }
+    }
+
+    if (len - 1 % 8 != 7) {
+        std::cerr << std::endl;
+    }
+}
+
+
 } // namespace aapt
diff --git a/tools/aapt2/Debug.h b/tools/aapt2/Debug.h
index 5b0d7d6..ba05be9 100644
--- a/tools/aapt2/Debug.h
+++ b/tools/aapt2/Debug.h
@@ -20,12 +20,16 @@
 #include "Resource.h"
 #include "ResourceTable.h"
 
+// Include for printf-like debugging.
+#include <iostream>
+
 namespace aapt {
 
 struct Debug {
     static void printTable(ResourceTable* table);
     static void printStyleGraph(ResourceTable* table,
                                 const ResourceName& targetStyle);
+    static void dumpHex(const void* data, size_t len);
 };
 
 } // namespace aapt
diff --git a/tools/aapt2/Flags.cpp b/tools/aapt2/Flags.cpp
index 9435396..666e8a8e 100644
--- a/tools/aapt2/Flags.cpp
+++ b/tools/aapt2/Flags.cpp
@@ -81,6 +81,8 @@
 }
 
 void Flags::usage(const StringPiece& command, std::ostream* out) {
+    constexpr size_t kWidth = 50;
+
     *out << command << " [options]";
     for (const Flag& flag : mFlags) {
         if (flag.required) {
@@ -100,11 +102,11 @@
         // the first line) followed by the description line. This will make sure that multiline
         // descriptions are still right justified and aligned.
         for (StringPiece line : util::tokenize<char>(flag.description, '\n')) {
-            *out << " " << std::setw(30) << std::left << argLine << line << "\n";
+            *out << " " << std::setw(kWidth) << std::left << argLine << line << "\n";
             argLine = " ";
         }
     }
-    *out << " " << std::setw(30) << std::left << "-h" << "Displays this help menu\n";
+    *out << " " << std::setw(kWidth) << std::left << "-h" << "Displays this help menu\n";
     out->flush();
 }
 
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 5e7d3ec..b37d366 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -70,6 +70,7 @@
  */
 struct ParsedResource {
     ResourceName name;
+    ConfigDescription config;
     Source source;
     ResourceId id;
     Maybe<SymbolState> symbolState;
@@ -108,8 +109,7 @@
 }
 
 // Recursively adds resources to the ResourceTable.
-static bool addResourcesToTable(ResourceTable* table, const ConfigDescription& config,
-                                IDiagnostics* diag, ParsedResource* res) {
+static bool addResourcesToTable(ResourceTable* table, IDiagnostics* diag, ParsedResource* res) {
     if (res->symbolState) {
         Symbol symbol;
         symbol.state = res->symbolState.value();
@@ -125,14 +125,14 @@
         res->value->setComment(std::move(res->comment));
         res->value->setSource(std::move(res->source));
 
-        if (!table->addResource(res->name, res->id, config, std::move(res->value), diag)) {
+        if (!table->addResource(res->name, res->id, res->config, std::move(res->value), diag)) {
             return false;
         }
     }
 
     bool error = false;
     for (ParsedResource& child : res->childResources) {
-        error |= !addResourcesToTable(table, config, diag, &child);
+        error |= !addResourcesToTable(table, diag, &child);
     }
     return !error;
 }
@@ -290,6 +290,7 @@
         }
 
         ParsedResource parsedResource;
+        parsedResource.config = mConfig;
         parsedResource.source = mSource.withLine(parser->getLineNumber());
         parsedResource.comment = std::move(comment);
 
@@ -310,7 +311,7 @@
             // Record that we stripped out this resource name.
             // We will check that at least one variant of this resource was included.
             strippedResources.insert(parsedResource.name);
-        } else if (!addResourcesToTable(mTable, mConfig, mDiag, &parsedResource)) {
+        } else if (!addResourcesToTable(mTable, mDiag, &parsedResource)) {
             error = true;
         }
     }
@@ -769,6 +770,13 @@
                                    bool weak) {
     outResource->name.type = ResourceType::kAttr;
 
+    // Attributes only end up in default configuration.
+    if (outResource->config != ConfigDescription::defaultConfig()) {
+        mDiag->warn(DiagMessage(outResource->source) << "ignoring configuration '"
+                    << outResource->config << "' for attribute " << outResource->name);
+        outResource->config = ConfigDescription::defaultConfig();
+    }
+
     uint32_t typeMask = 0;
 
     Maybe<StringPiece16> maybeFormat = xml::findAttribute(parser, u"format");
@@ -940,8 +948,7 @@
     }
 
     return Attribute::Symbol{
-            Reference(ResourceNameRef({}, ResourceType::kId, maybeName.value())),
-            val.data };
+            Reference(ResourceNameRef({}, ResourceType::kId, maybeName.value())), val.data };
 }
 
 static Maybe<Reference> parseXmlAttributeName(StringPiece16 str) {
@@ -1190,12 +1197,21 @@
     return true;
 }
 
-bool ResourceParser::parseDeclareStyleable(xml::XmlPullParser* parser, ParsedResource* outResource) {
+bool ResourceParser::parseDeclareStyleable(xml::XmlPullParser* parser,
+                                           ParsedResource* outResource) {
     outResource->name.type = ResourceType::kStyleable;
 
     // Declare-styleable is kPrivate by default, because it technically only exists in R.java.
     outResource->symbolState = SymbolState::kPublic;
 
+    // Declare-styleable only ends up in default config;
+    if (outResource->config != ConfigDescription::defaultConfig()) {
+        mDiag->warn(DiagMessage(outResource->source) << "ignoring configuration '"
+                            << outResource->config << "' for styleable "
+                            << outResource->name.entry);
+        outResource->config = ConfigDescription::defaultConfig();
+    }
+
     std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
 
     std::u16string comment;
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 8d10ba1..cf0fcd1 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -47,13 +47,26 @@
         mContext = test::ContextBuilder().build();
     }
 
+    ::testing::AssertionResult testParse(const StringPiece& str) {
+        return testParse(str, ConfigDescription{}, {});
+    }
+
+    ::testing::AssertionResult testParse(const StringPiece& str, const ConfigDescription& config) {
+        return testParse(str, config, {});
+    }
+
     ::testing::AssertionResult testParse(const StringPiece& str,
-                                         std::initializer_list<std::u16string> products = {}) {
+                                         std::initializer_list<std::u16string> products) {
+        return testParse(str, {}, std::move(products));
+    }
+
+    ::testing::AssertionResult testParse(const StringPiece& str, const ConfigDescription& config,
+                                         std::initializer_list<std::u16string> products) {
         std::stringstream input(kXmlPreamble);
         input << "<resources>\n" << str << "\n</resources>" << std::endl;
         ResourceParserOptions parserOptions;
         parserOptions.products = products;
-        ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{ "test" }, {},
+        ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{ "test" }, config,
                               parserOptions);
         xml::XmlPullParser xmlParser(input);
         if (parser.parse(&xmlParser)) {
@@ -138,6 +151,26 @@
     EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->typeMask);
 }
 
+// Old AAPT allowed attributes to be defined under different configurations, but ultimately
+// stored them with the default configuration. Check that we have the same behavior.
+TEST_F(ResourceParserTest, ParseAttrAndDeclareStyleableUnderConfigButRecordAsNoConfig) {
+    const ConfigDescription watchConfig = test::parseConfigOrDie("watch");
+    std::string input = R"EOF(
+        <attr name="foo" />
+        <declare-styleable name="bar">
+          <attr name="baz" />
+        </declare-styleable>)EOF";
+    ASSERT_TRUE(testParse(input, watchConfig));
+
+    EXPECT_EQ(nullptr, test::getValueForConfig<Attribute>(&mTable, u"@attr/foo", watchConfig));
+    EXPECT_EQ(nullptr, test::getValueForConfig<Attribute>(&mTable, u"@attr/baz", watchConfig));
+    EXPECT_EQ(nullptr, test::getValueForConfig<Styleable>(&mTable, u"@styleable/bar", watchConfig));
+
+    EXPECT_NE(nullptr, test::getValue<Attribute>(&mTable, u"@attr/foo"));
+    EXPECT_NE(nullptr, test::getValue<Attribute>(&mTable, u"@attr/baz"));
+    EXPECT_NE(nullptr, test::getValue<Styleable>(&mTable, u"@styleable/bar"));
+}
+
 TEST_F(ResourceParserTest, ParseAttrWithMinMax) {
     std::string input = "<attr name=\"foo\" min=\"10\" max=\"23\" format=\"integer\"/>";
     ASSERT_TRUE(testParse(input));
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 1dc123e..07f62af 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -176,7 +176,7 @@
 /*
  * Style parent's are a bit different. We accept the following formats:
  *
- * @[[*]package:]style/<entry>
+ * @[[*]package:][style/]<entry>
  * ?[[*]package:]style/<entry>
  * <[*]package>:[style/]<entry>
  * [[*]package:style/]<entry>
@@ -216,14 +216,6 @@
             *outError = err.str();
             return {};
         }
-    } else {
-        // No type was defined, this should not have a leading identifier.
-        if (hasLeadingIdentifiers) {
-            std::stringstream err;
-            err << "invalid parent reference '" << str << "'";
-            *outError = err.str();
-            return {};
-        }
     }
 
     if (!hasLeadingIdentifiers && ref.package.empty() && !typeStr.empty()) {
@@ -294,6 +286,12 @@
                                                     const StringPiece16& str) {
     android::Res_value flags = { };
     flags.dataType = android::Res_value::TYPE_INT_DEC;
+    flags.data = 0u;
+
+    if (util::trimWhitespace(str).empty()) {
+        // Empty string is a valid flag (0).
+        return util::make_unique<BinaryPrimitive>(flags);
+    }
 
     for (StringPiece16 part : util::tokenize(str, u'|')) {
         StringPiece16 trimmedPart = util::trimWhitespace(part);
@@ -386,12 +384,12 @@
 
 bool tryParseBool(const StringPiece16& str, bool* outValue) {
     StringPiece16 trimmedStr(util::trimWhitespace(str));
-    if (trimmedStr == u"true" || trimmedStr == u"TRUE") {
+    if (trimmedStr == u"true" || trimmedStr == u"TRUE" || trimmedStr == u"True") {
         if (outValue) {
             *outValue = true;
         }
         return true;
-    } else if (trimmedStr == u"false" || trimmedStr == u"FALSE") {
+    } else if (trimmedStr == u"false" || trimmedStr == u"FALSE" || trimmedStr == u"False") {
         if (outValue) {
             *outValue = false;
         }
diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp
index 88efa67..c9f93e1 100644
--- a/tools/aapt2/ResourceUtils_test.cpp
+++ b/tools/aapt2/ResourceUtils_test.cpp
@@ -16,12 +16,34 @@
 
 #include "Resource.h"
 #include "ResourceUtils.h"
+#include "test/Builders.h"
 #include "test/Common.h"
 
 #include <gtest/gtest.h>
 
 namespace aapt {
 
+TEST(ResourceUtilsTest, ParseBool) {
+    bool val = false;
+    EXPECT_TRUE(ResourceUtils::tryParseBool(u"true", &val));
+    EXPECT_TRUE(val);
+
+    EXPECT_TRUE(ResourceUtils::tryParseBool(u"TRUE", &val));
+    EXPECT_TRUE(val);
+
+    EXPECT_TRUE(ResourceUtils::tryParseBool(u"True", &val));
+    EXPECT_TRUE(val);
+
+    EXPECT_TRUE(ResourceUtils::tryParseBool(u"false", &val));
+    EXPECT_FALSE(val);
+
+    EXPECT_TRUE(ResourceUtils::tryParseBool(u"FALSE", &val));
+    EXPECT_FALSE(val);
+
+    EXPECT_TRUE(ResourceUtils::tryParseBool(u"False", &val));
+    EXPECT_FALSE(val);
+}
+
 TEST(ResourceUtilsTest, ParseResourceName) {
     ResourceNameRef actual;
     bool actualPriv = false;
@@ -154,6 +176,10 @@
     AAPT_ASSERT_TRUE(ref);
     EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
 
+    ref = ResourceUtils::parseStyleParentReference(u"@android:foo", &errStr);
+    AAPT_ASSERT_TRUE(ref);
+    EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName);
+
     ref = ResourceUtils::parseStyleParentReference(u"foo", &errStr);
     AAPT_ASSERT_TRUE(ref);
     EXPECT_EQ(ref.value().name.value(), kStyleFooName);
@@ -164,4 +190,16 @@
     EXPECT_TRUE(ref.value().privateReference);
 }
 
+TEST(ResourceUtilsTest, ParseEmptyFlag) {
+    std::unique_ptr<Attribute> attr = test::AttributeBuilder(false)
+            .setTypeMask(android::ResTable_map::TYPE_FLAGS)
+            .addItem(u"one", 0x01)
+            .addItem(u"two", 0x02)
+            .build();
+
+    std::unique_ptr<BinaryPrimitive> result = ResourceUtils::tryParseFlagSymbol(attr.get(), u"");
+    ASSERT_NE(nullptr, result);
+    EXPECT_EQ(0u, result->value.data);
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/StringPool.cpp b/tools/aapt2/StringPool.cpp
index 8552f47..aadb00b 100644
--- a/tools/aapt2/StringPool.cpp
+++ b/tools/aapt2/StringPool.cpp
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
+#include "StringPool.h"
 #include "util/BigBuffer.h"
 #include "util/StringPiece.h"
-#include "StringPool.h"
 #include "util/Util.h"
 
 #include <algorithm>
@@ -342,7 +342,14 @@
 
             // Encode the actual UTF16 string length.
             data = encodeLength(data, entry->value.size());
-            strncpy16(data, entry->value.data(), entry->value.size());
+            const size_t byteLength = entry->value.size() * sizeof(char16_t);
+
+            // NOTE: For some reason, strncpy16(data, entry->value.data(), entry->value.size())
+            // truncates the string.
+            memcpy(data, entry->value.data(), byteLength);
+
+            // The null-terminating character is already here due to the block of data being set
+            // to 0s on allocation.
         }
     }
 
diff --git a/tools/aapt2/StringPool_test.cpp b/tools/aapt2/StringPool_test.cpp
index c722fbe..e93c2fba 100644
--- a/tools/aapt2/StringPool_test.cpp
+++ b/tools/aapt2/StringPool_test.cpp
@@ -180,6 +180,22 @@
     ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
 }
 
+TEST(StringPoolTest, FlattenOddCharactersUtf16) {
+    StringPool pool;
+    pool.makeRef(u"\u093f");
+    BigBuffer buffer(1024);
+    StringPool::flattenUtf16(&buffer, pool);
+
+    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
+    android::ResStringPool test;
+    ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
+    size_t len = 0;
+    const char16_t* str = test.stringAt(0, &len);
+    EXPECT_EQ(1u, len);
+    EXPECT_EQ(u'\u093f', *str);
+    EXPECT_EQ(0u, str[1]);
+}
+
 constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。";
 
 TEST(StringPoolTest, FlattenUtf8) {
diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp
index c78670f..689ace6 100644
--- a/tools/aapt2/compile/Compile.cpp
+++ b/tools/aapt2/compile/Compile.cpp
@@ -117,7 +117,11 @@
     if (!data.configStr.empty()) {
         name << "-" << data.configStr;
     }
-    name << "_" << data.name << "." << data.extension << ".flat";
+    name << "_" << data.name;
+    if (!data.extension.empty()) {
+        name << "." << data.extension;
+    }
+    name << ".flat";
     return name.str();
 }
 
@@ -386,16 +390,26 @@
     fileExportWriter.getChunkHeader()->size =
             util::hostToDevice32(buffer.size() + f.value().getDataLength());
 
-    if (writer->writeEntry(buffer)) {
-        if (writer->writeEntry(f.value().getDataPtr(), f.value().getDataLength())) {
-            if (writer->finishEntry()) {
-                return true;
-            }
+    if (!writer->writeEntry(buffer)) {
+        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+        return false;
+    }
+
+    // Only write if we have something to write. This is because mmap fails with length of 0,
+    // but we still want to compile the file to get the resource ID.
+    if (f.value().getDataPtr() && f.value().getDataLength() > 0) {
+        if (!writer->writeEntry(f.value().getDataPtr(), f.value().getDataLength())) {
+            context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+            return false;
         }
     }
 
-    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
-    return false;
+    if (!writer->finishEntry()) {
+        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+        return false;
+    }
+
+    return true;
 }
 
 class CompileContext : public IAaptContext {
diff --git a/tools/aapt2/io/Data.h b/tools/aapt2/io/Data.h
index 9081c55..467e604 100644
--- a/tools/aapt2/io/Data.h
+++ b/tools/aapt2/io/Data.h
@@ -79,6 +79,21 @@
     size_t mSize;
 };
 
+/**
+ * When mmap fails because the file has length 0, we use the EmptyData to simulate data of length 0.
+ */
+class EmptyData : public IData {
+public:
+    const void* data() const override {
+        static const uint8_t d = 0;
+        return &d;
+    }
+
+    size_t size() const override {
+        return 0u;
+    }
+};
+
 } // namespace io
 } // namespace aapt
 
diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp
index 76f87ae..e758d8a4 100644
--- a/tools/aapt2/io/FileSystem.cpp
+++ b/tools/aapt2/io/FileSystem.cpp
@@ -32,7 +32,10 @@
 std::unique_ptr<IData> RegularFile::openAsData() {
     android::FileMap map;
     if (Maybe<android::FileMap> map = file::mmapPath(mSource.path, nullptr)) {
-        return util::make_unique<MmappedData>(std::move(map.value()));
+        if (map.value().getDataPtr() && map.value().getDataLength() > 0) {
+            return util::make_unique<MmappedData>(std::move(map.value()));
+        }
+        return util::make_unique<EmptyData>();
     }
     return {};
 }
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 8a87d96..51b9cec 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -51,16 +51,19 @@
     std::vector<std::string> includePaths;
     std::vector<std::string> overlayFiles;
     Maybe<std::string> generateJavaClassPath;
-    std::set<std::string> extraJavaPackages;
+    Maybe<std::u16string> customJavaPackage;
+    std::set<std::u16string> extraJavaPackages;
     Maybe<std::string> generateProguardRulesPath;
     bool noAutoVersion = false;
     bool staticLib = false;
     bool verbose = false;
     bool outputToDirectory = false;
     bool autoAddOverlay = false;
+    bool doNotCompressAnything = false;
+    std::vector<std::string> extensionsToNotCompress;
     Maybe<std::u16string> privateSymbols;
-    Maybe<std::u16string> minSdkVersionDefault;
-    Maybe<std::u16string> targetSdkVersionDefault;
+    ManifestFixerOptions manifestFixerOptions;
+
 };
 
 struct LinkContext : public IAaptContext {
@@ -186,7 +189,20 @@
         return resFile;
     }
 
-    bool copyFileToArchive(io::IFile* file, const std::string& outPath, uint32_t flags,
+    uint32_t getCompressionFlags(const StringPiece& str) {
+        if (mOptions.doNotCompressAnything) {
+            return 0;
+        }
+
+        for (const std::string& extension : mOptions.extensionsToNotCompress) {
+            if (util::stringEndsWith<char>(str, extension)) {
+                return 0;
+            }
+        }
+        return ArchiveEntry::kCompress;
+    }
+
+    bool copyFileToArchive(io::IFile* file, const std::string& outPath,
                            IArchiveWriter* writer) {
         std::unique_ptr<io::IData> data = file->openAsData();
         if (!data) {
@@ -202,7 +218,7 @@
             return false;
         }
 
-        if (writer->startEntry(outPath, flags)) {
+        if (writer->startEntry(outPath, getCompressionFlags(outPath))) {
             if (writer->writeEntry(reinterpret_cast<const uint8_t*>(data->data()) + offset,
                                    data->size() - static_cast<size_t>(offset))) {
                 if (writer->finishEntry()) {
@@ -319,7 +335,6 @@
             return false;
         }
 
-
         if (writer->startEntry(path, ArchiveEntry::kCompress)) {
             if (writer->writeEntry(buffer)) {
                 if (writer->finishEntry()) {
@@ -508,7 +523,10 @@
     }
 
     bool processFile(const std::string& path, bool override) {
-        if (util::stringEndsWith<char>(path, ".flata")) {
+        if (util::stringEndsWith<char>(path, ".flata") ||
+                util::stringEndsWith<char>(path, ".jar") ||
+                util::stringEndsWith<char>(path, ".jack") ||
+                util::stringEndsWith<char>(path, ".zip")) {
             return mergeArchive(path, override);
         }
 
@@ -520,7 +538,7 @@
         const Source& src = file->getSource();
         if (util::stringEndsWith<char>(src.path, ".arsc.flat")) {
             return mergeResourceTable(file, override);
-        } else {
+        } else if (util::stringEndsWith<char>(src.path, ".flat")){
             // Try opening the file and looking for an Export header.
             std::unique_ptr<io::IData> data = file->openAsData();
             if (!data) {
@@ -533,7 +551,11 @@
             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;
     }
 
@@ -646,10 +668,7 @@
 
         bool error = false;
         {
-            ManifestFixerOptions manifestFixerOptions;
-            manifestFixerOptions.minSdkVersionDefault = mOptions.minSdkVersionDefault;
-            manifestFixerOptions.targetSdkVersionDefault = mOptions.targetSdkVersionDefault;
-            ManifestFixer manifestFixer(manifestFixerOptions);
+            ManifestFixer manifestFixer(mOptions.manifestFixerOptions);
             if (!manifestFixer.consume(&mContext, manifestXml.get())) {
                 error = true;
             }
@@ -786,7 +805,7 @@
                     mContext.getDiagnostics()->note(DiagMessage() << "copying " << path);
                 }
 
-                if (!copyFileToArchive(fileToMerge.file, fileToMerge.dstPath, 0,
+                if (!copyFileToArchive(fileToMerge.file, fileToMerge.dstPath,
                                        archiveWriter.get())) {
                     error = true;
                 }
@@ -813,12 +832,18 @@
 
         if (mOptions.generateJavaClassPath) {
             JavaClassGeneratorOptions options;
+            options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
+
             if (mOptions.staticLib) {
                 options.useFinal = false;
             }
 
-            StringPiece16 actualPackage = mContext.getCompilationPackage();
+            const StringPiece16 actualPackage = mContext.getCompilationPackage();
             StringPiece16 outputPackage = mContext.getCompilationPackage();
+            if (mOptions.customJavaPackage) {
+                // Override the output java package to the custom one.
+                outputPackage = mOptions.customJavaPackage.value();
+            }
 
             if (mOptions.privateSymbols) {
                 // If we defined a private symbols package, we only emit Public symbols
@@ -826,7 +851,7 @@
 
                 options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
                 if (!writeJavaFile(&mFinalTable, mContext.getCompilationPackage(),
-                                   mContext.getCompilationPackage(), options)) {
+                                   outputPackage, options)) {
                     return 1;
                 }
 
@@ -838,9 +863,8 @@
                 return 1;
             }
 
-            for (const std::string& extraPackage : mOptions.extraJavaPackages) {
-                if (!writeJavaFile(&mFinalTable, actualPackage, util::utf8ToUtf16(extraPackage),
-                                   options)) {
+            for (const std::u16string& extraPackage : mOptions.extraJavaPackages) {
+                if (!writeJavaFile(&mFinalTable, actualPackage, extraPackage, options)) {
                     return 1;
                 }
             }
@@ -877,13 +901,16 @@
     LinkOptions options;
     Maybe<std::string> privateSymbolsPackage;
     Maybe<std::string> minSdkVersion, targetSdkVersion;
+    Maybe<std::string> renameManifestPackage, renameInstrumentationTargetPackage;
+    Maybe<std::string> versionCode, versionName;
+    Maybe<std::string> customJavaPackage;
     std::vector<std::string> extraJavaPackages;
     Flags flags = Flags()
             .requiredFlag("-o", "Output path", &options.outputPath)
             .requiredFlag("--manifest", "Path to the Android manifest to build",
                           &options.manifestPath)
             .optionalFlagList("-I", "Adds an Android APK to link against", &options.includePaths)
-            .optionalFlagList("-R", "Compilation unit to link, using `overlay` semantics. "
+            .optionalFlagList("-R", "Compilation unit to link, using `overlay` semantics.\n"
                               "The last conflicting resource given takes precedence.",
                               &options.overlayFiles)
             .optionalFlag("--java", "Directory in which to generate R.java",
@@ -900,15 +927,29 @@
                           "AndroidManifest.xml", &minSdkVersion)
             .optionalFlag("--target-sdk-version", "Default target SDK version to use for "
                           "AndroidManifest.xml", &targetSdkVersion)
+            .optionalFlag("--version-code", "Version code (integer) to inject into the "
+                          "AndroidManifest.xml if none is present", &versionCode)
+            .optionalFlag("--version-name", "Version name to inject into the AndroidManifest.xml "
+                          "if none is present", &versionName)
             .optionalSwitch("--static-lib", "Generate a static Android library", &options.staticLib)
             .optionalFlag("--private-symbols", "Package name to use when generating R.java for "
                           "private symbols.\n"
                           "If not specified, public and private symbols will use the application's "
                           "package name", &privateSymbolsPackage)
+            .optionalFlag("--custom-package", "Custom Java package under which to generate R.java",
+                          &customJavaPackage)
             .optionalFlagList("--extra-packages", "Generate the same R.java but with different "
                               "package names", &extraJavaPackages)
             .optionalSwitch("--auto-add-overlay", "Allows the addition of new resources in "
                             "overlays without <add-resource> tags", &options.autoAddOverlay)
+            .optionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml",
+                          &renameManifestPackage)
+            .optionalFlag("--rename-instrumentation-target-package",
+                          "Changes the name of the target package for instrumentation. Most useful "
+                          "when used\nin conjunction with --rename-manifest-package",
+                          &renameInstrumentationTargetPackage)
+            .optionalFlagList("-0", "File extensions not to compress",
+                              &options.extensionsToNotCompress)
             .optionalSwitch("-v", "Enables verbose logging", &options.verbose);
 
     if (!flags.parse("aapt2 link", args, &std::cerr)) {
@@ -920,18 +961,42 @@
     }
 
     if (minSdkVersion) {
-        options.minSdkVersionDefault = util::utf8ToUtf16(minSdkVersion.value());
+        options.manifestFixerOptions.minSdkVersionDefault =
+                util::utf8ToUtf16(minSdkVersion.value());
     }
 
     if (targetSdkVersion) {
-        options.targetSdkVersionDefault = util::utf8ToUtf16(targetSdkVersion.value());
+        options.manifestFixerOptions.targetSdkVersionDefault =
+                util::utf8ToUtf16(targetSdkVersion.value());
+    }
+
+    if (renameManifestPackage) {
+        options.manifestFixerOptions.renameManifestPackage =
+                util::utf8ToUtf16(renameManifestPackage.value());
+    }
+
+    if (renameInstrumentationTargetPackage) {
+        options.manifestFixerOptions.renameInstrumentationTargetPackage =
+                util::utf8ToUtf16(renameInstrumentationTargetPackage.value());
+    }
+
+    if (versionCode) {
+        options.manifestFixerOptions.versionCodeDefault = util::utf8ToUtf16(versionCode.value());
+    }
+
+    if (versionName) {
+        options.manifestFixerOptions.versionNameDefault = util::utf8ToUtf16(versionName.value());
+    }
+
+    if (customJavaPackage) {
+        options.customJavaPackage = util::utf8ToUtf16(customJavaPackage.value());
     }
 
     // Populate the set of extra packages for which to generate R.java.
     for (std::string& extraPackage : extraJavaPackages) {
         // A given package can actually be a colon separated list of packages.
         for (StringPiece package : util::split(extraPackage, ':')) {
-            options.extraJavaPackages.insert(package.toString());
+            options.extraJavaPackages.insert(util::utf8ToUtf16(package));
         }
     }
 
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 2034c57..9baf1d8 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -22,25 +22,43 @@
 namespace aapt {
 
 static bool verifyManifest(IAaptContext* context, const Source& source, xml::Element* manifestEl) {
-    bool error = false;
-
     xml::Attribute* attr = manifestEl->findAttribute({}, u"package");
     if (!attr) {
         context->getDiagnostics()->error(DiagMessage(source.withLine(manifestEl->lineNumber))
                                          << "missing 'package' attribute");
-        error = true;
     } else if (ResourceUtils::isReference(attr->value)) {
         context->getDiagnostics()->error(DiagMessage(source.withLine(manifestEl->lineNumber))
                                          << "value for attribute 'package' must not be a "
                                             "reference");
-        error = true;
     } else if (!util::isJavaPackageName(attr->value)) {
         context->getDiagnostics()->error(DiagMessage(source.withLine(manifestEl->lineNumber))
                                          << "invalid package name '" << attr->value << "'");
-        error = true;
+    } else {
+        return true;
+    }
+    return false;
+}
+
+static bool includeVersionName(IAaptContext* context, const Source& source,
+                               const StringPiece16& versionName, xml::Element* manifestEl) {
+    if (manifestEl->findAttribute(xml::kSchemaAndroid, u"versionName")) {
+        return true;
     }
 
-    return !error;
+    manifestEl->attributes.push_back(xml::Attribute{
+            xml::kSchemaAndroid, u"versionName", versionName.toString() });
+    return true;
+}
+
+static bool includeVersionCode(IAaptContext* context, const Source& source,
+                               const StringPiece16& versionCode, xml::Element* manifestEl) {
+    if (manifestEl->findAttribute(xml::kSchemaAndroid, u"versionCode")) {
+        return true;
+    }
+
+    manifestEl->attributes.push_back(xml::Attribute{
+            xml::kSchemaAndroid, u"versionCode", versionCode.toString() });
+    return true;
 }
 
 static bool fixUsesSdk(IAaptContext* context, const Source& source, xml::Element* el,
@@ -62,6 +80,76 @@
     return true;
 }
 
+class FullyQualifiedClassNameVisitor : public xml::Visitor {
+public:
+    using xml::Visitor::visit;
+
+    FullyQualifiedClassNameVisitor(const StringPiece16& package) : mPackage(package) {
+    }
+
+    void visit(xml::Element* el) override {
+        for (xml::Attribute& attr : el->attributes) {
+            if (Maybe<std::u16string> newValue =
+                    util::getFullyQualifiedClassName(mPackage, attr.value)) {
+                attr.value = std::move(newValue.value());
+            }
+        }
+
+        // Super implementation to iterate over the children.
+        xml::Visitor::visit(el);
+    }
+
+private:
+    StringPiece16 mPackage;
+};
+
+static bool renameManifestPackage(IAaptContext* context, const Source& source,
+                                  const StringPiece16& packageOverride, xml::Element* manifestEl) {
+    if (!util::isJavaPackageName(packageOverride)) {
+        context->getDiagnostics()->error(DiagMessage() << "invalid manifest package override '"
+                                         << packageOverride << "'");
+        return false;
+    }
+
+    xml::Attribute* attr = manifestEl->findAttribute({}, u"package");
+
+    // We've already verified that the manifest element is present, with a package name specified.
+    assert(attr);
+
+    std::u16string originalPackage = std::move(attr->value);
+    attr->value = packageOverride.toString();
+
+    FullyQualifiedClassNameVisitor visitor(originalPackage);
+    manifestEl->accept(&visitor);
+    return true;
+}
+
+static bool renameInstrumentationTargetPackage(IAaptContext* context, const Source& source,
+                                               const StringPiece16& packageOverride,
+                                               xml::Element* manifestEl) {
+    if (!util::isJavaPackageName(packageOverride)) {
+        context->getDiagnostics()->error(DiagMessage()
+                                         << "invalid instrumentation target package override '"
+                                         << packageOverride << "'");
+        return false;
+    }
+
+    xml::Element* instrumentationEl = manifestEl->findChild({}, u"instrumentation");
+    if (!instrumentationEl) {
+        // No error if there is no work to be done.
+        return true;
+    }
+
+    xml::Attribute* attr = instrumentationEl->findAttribute(xml::kSchemaAndroid, u"targetPackage");
+    if (!attr) {
+        // No error if there is no work to be done.
+        return true;
+    }
+
+    attr->value = packageOverride.toString();
+    return true;
+}
+
 bool ManifestFixer::consume(IAaptContext* context, xml::XmlResource* doc) {
     xml::Element* root = xml::findRootElement(doc->root.get());
     if (!root || !root->namespaceUri.empty() || root->name != u"manifest") {
@@ -74,6 +162,36 @@
         return false;
     }
 
+    if (mOptions.versionCodeDefault) {
+        if (!includeVersionCode(context, doc->file.source, mOptions.versionCodeDefault.value(),
+                                root)) {
+            return false;
+        }
+    }
+
+    if (mOptions.versionNameDefault) {
+        if (!includeVersionName(context, doc->file.source, mOptions.versionNameDefault.value(),
+                                root)) {
+            return false;
+        }
+    }
+
+    if (mOptions.renameManifestPackage) {
+        // Rename manifest package.
+        if (!renameManifestPackage(context, doc->file.source,
+                                   mOptions.renameManifestPackage.value(), root)) {
+            return false;
+        }
+    }
+
+    if (mOptions.renameInstrumentationTargetPackage) {
+        if (!renameInstrumentationTargetPackage(context, doc->file.source,
+                                                mOptions.renameInstrumentationTargetPackage.value(),
+                                                root)) {
+            return false;
+        }
+    }
+
     bool foundUsesSdk = false;
     for (xml::Element* el : root->getChildElements()) {
         if (!el->namespaceUri.empty()) {
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index a77e6d5..b8d9c83 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -28,6 +28,10 @@
 struct ManifestFixerOptions {
     Maybe<std::u16string> minSdkVersionDefault;
     Maybe<std::u16string> targetSdkVersionDefault;
+    Maybe<std::u16string> renameManifestPackage;
+    Maybe<std::u16string> renameInstrumentationTargetPackage;
+    Maybe<std::u16string> versionNameDefault;
+    Maybe<std::u16string> versionCodeDefault;
 };
 
 /**
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index f6bf895..f40fbfb 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -82,8 +82,6 @@
     EXPECT_EQ(nullptr, verify("<manifest package=\"@string/str\" />"));
 }
 
-
-
 TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
     ManifestFixerOptions options = { std::u16string(u"8"), std::u16string(u"22") };
 
@@ -97,7 +95,7 @@
     xml::Element* el;
     xml::Attribute* attr;
 
-    el = xml::findRootElement(doc->root.get());
+    el = xml::findRootElement(doc.get());
     ASSERT_NE(nullptr, el);
     el = el->findChild({}, u"uses-sdk");
     ASSERT_NE(nullptr, el);
@@ -115,7 +113,7 @@
       </manifest>)EOF", options);
     ASSERT_NE(nullptr, doc);
 
-    el = xml::findRootElement(doc->root.get());
+    el = xml::findRootElement(doc.get());
     ASSERT_NE(nullptr, el);
     el = el->findChild({}, u"uses-sdk");
     ASSERT_NE(nullptr, el);
@@ -133,7 +131,7 @@
       </manifest>)EOF", options);
     ASSERT_NE(nullptr, doc);
 
-    el = xml::findRootElement(doc->root.get());
+    el = xml::findRootElement(doc.get());
     ASSERT_NE(nullptr, el);
     el = el->findChild({}, u"uses-sdk");
     ASSERT_NE(nullptr, el);
@@ -149,7 +147,7 @@
                 package="android" />)EOF", options);
     ASSERT_NE(nullptr, doc);
 
-    el = xml::findRootElement(doc->root.get());
+    el = xml::findRootElement(doc.get());
     ASSERT_NE(nullptr, el);
     el = el->findChild({}, u"uses-sdk");
     ASSERT_NE(nullptr, el);
@@ -161,4 +159,98 @@
     EXPECT_EQ(u"22", attr->value);
 }
 
+TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) {
+    ManifestFixerOptions options;
+    options.renameManifestPackage = std::u16string(u"com.android");
+
+    std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                package="android">
+        <application name=".MainApplication" text="hello">
+          <activity name=".activity.Start" />
+          <receiver name="com.google.android.Receiver" />
+        </application>
+      </manifest>)EOF", options);
+    ASSERT_NE(nullptr, doc);
+
+    xml::Element* manifestEl = xml::findRootElement(doc.get());
+    ASSERT_NE(nullptr, manifestEl);
+
+    xml::Attribute* attr = nullptr;
+
+    attr = manifestEl->findAttribute({}, u"package");
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(std::u16string(u"com.android"), attr->value);
+
+    xml::Element* applicationEl = manifestEl->findChild({}, u"application");
+    ASSERT_NE(nullptr, applicationEl);
+
+    attr = applicationEl->findAttribute({}, u"name");
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(std::u16string(u"android.MainApplication"), attr->value);
+
+    attr = applicationEl->findAttribute({}, u"text");
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(std::u16string(u"hello"), attr->value);
+
+    xml::Element* el;
+    el = applicationEl->findChild({}, u"activity");
+    ASSERT_NE(nullptr, el);
+
+    attr = el->findAttribute({}, u"name");
+    ASSERT_NE(nullptr, el);
+    EXPECT_EQ(std::u16string(u"android.activity.Start"), attr->value);
+
+    el = applicationEl->findChild({}, u"receiver");
+    ASSERT_NE(nullptr, el);
+
+    attr = el->findAttribute({}, u"name");
+    ASSERT_NE(nullptr, el);
+    EXPECT_EQ(std::u16string(u"com.google.android.Receiver"), attr->value);
+}
+
+TEST_F(ManifestFixerTest, RenameManifestInstrumentationPackageAndFullyQualifyTarget) {
+    ManifestFixerOptions options;
+    options.renameInstrumentationTargetPackage = std::u16string(u"com.android");
+
+    std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                package="android">
+        <instrumentation android:targetPackage="android" />
+      </manifest>)EOF", options);
+    ASSERT_NE(nullptr, doc);
+
+    xml::Element* manifestEl = xml::findRootElement(doc.get());
+    ASSERT_NE(nullptr, manifestEl);
+
+    xml::Element* instrumentationEl = manifestEl->findChild({}, u"instrumentation");
+    ASSERT_NE(nullptr, instrumentationEl);
+
+    xml::Attribute* attr = instrumentationEl->findAttribute(xml::kSchemaAndroid, u"targetPackage");
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(std::u16string(u"com.android"), attr->value);
+}
+
+TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
+    ManifestFixerOptions options;
+    options.versionNameDefault = std::u16string(u"Beta");
+    options.versionCodeDefault = std::u16string(u"0x10000000");
+
+    std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                package="android" />)EOF", options);
+    ASSERT_NE(nullptr, doc);
+
+    xml::Element* manifestEl = xml::findRootElement(doc.get());
+    ASSERT_NE(nullptr, manifestEl);
+
+    xml::Attribute* attr = manifestEl->findAttribute(xml::kSchemaAndroid, u"versionName");
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(std::u16string(u"Beta"), attr->value);
+
+    attr = manifestEl->findAttribute(xml::kSchemaAndroid, u"versionCode");
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(std::u16string(u"0x10000000"), attr->value);
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index a81dc7b..04e8199 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -163,6 +163,11 @@
     }
 
     android::FileMap fileMap;
+    if (fileStats.st_size == 0) {
+        // mmap doesn't like a length of 0. Instead we return an empty FileMap.
+        return std::move(fileMap);
+    }
+
     if (!fileMap.create(path.data(), fd, 0, fileStats.st_size, true)) {
         if (outError) *outError = strerror(errno);
         return {};
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp
index 9ecc974..7b0c71d 100644
--- a/tools/aapt2/util/Util.cpp
+++ b/tools/aapt2/util/Util.cpp
@@ -175,10 +175,11 @@
         return {};
     }
 
-    std::u16string result(package.data(), package.size());
     if (className.data()[0] != u'.') {
-        result += u'.';
+        return {};
     }
+
+    std::u16string result(package.data(), package.size());
     result.append(className.data(), className.size());
     if (!isJavaClassName(result)) {
         return {};
diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp
index 9208e07..1e0c7fa 100644
--- a/tools/aapt2/util/Util_test.cpp
+++ b/tools/aapt2/util/Util_test.cpp
@@ -144,8 +144,7 @@
 
 TEST(UtilTest, FullyQualifiedClassName) {
     Maybe<std::u16string> res = util::getFullyQualifiedClassName(u"android", u"asdf");
-    AAPT_ASSERT_TRUE(res);
-    EXPECT_EQ(res.value(), u"android.asdf");
+    AAPT_ASSERT_FALSE(res);
 
     res = util::getFullyQualifiedClassName(u"android", u".asdf");
     AAPT_ASSERT_TRUE(res);
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
index 54021c9..28a489a 100644
--- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
@@ -64,7 +64,8 @@
     private static long registerMethod(Class<?> targetClass, String methodName, Class[] types,
             int nArgs) {
         // Encode the number of arguments in the method name
-        String methodIndexName = String.format("%1$s#%2$d", methodName, nArgs);
+        String methodIndexName = String.format("%1$s.%2$s#%3$d", targetClass.getSimpleName(),
+                methodName, nArgs);
         synchronized (sMethodIndexLock) {
             Long methodId = METHOD_NAME_TO_ID.get(methodIndexName);
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 64cd503..ba0d399 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -35,7 +35,6 @@
 import java.awt.Shape;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Arc2D;
-import java.awt.geom.Path2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 
@@ -713,8 +712,27 @@
                         if (bounds.isEmpty()) {
                             // Apple JRE 1.6 doesn't like drawing empty shapes.
                             // http://b.android.com/178278
-                            return;
+
+                            if (pathDelegate.isEmpty()) {
+                                // This means that the path doesn't have any lines or curves so
+                                // nothing to draw.
+                                return;
+                            }
+
+                            // The stroke width is not consider for the size of the bounds so,
+                            // for example, a horizontal line, would be considered as an empty
+                            // rectangle.
+                            // If the strokeWidth is not 0, we use it to consider the size of the
+                            // path as well.
+                            float strokeWidth = paintDelegate.getStrokeWidth();
+                            if (strokeWidth <= 0.0f) {
+                                return;
+                            }
+                            bounds.setRect(bounds.getX(), bounds.getY(),
+                                    Math.max(strokeWidth, bounds.getWidth()),
+                                    Math.max(strokeWidth, bounds.getHeight()));
                         }
+
                         int style = paintDelegate.getStyle();
 
                         if (style == Paint.Style.FILL.nativeInt ||
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index a545283..dbd45c4 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -152,11 +152,7 @@
      * returns the value of stroke miter needed by the java api.
      */
     public float getJavaStrokeMiter() {
-        float miter = mStrokeMiter * mStrokeWidth;
-        if (miter < 1.f) {
-            miter = 1.f;
-        }
-        return miter;
+        return mStrokeMiter;
     }
 
     public int getJavaCap() {
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
index 3c71233..fc9b4f7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
@@ -19,10 +19,12 @@
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.util.CachedPathIteratorFactory;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
+import com.android.layoutlib.bridge.util.CachedPathIteratorFactory.CachedPathIterator;
+
 import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
 
 /**
  * Delegate implementing the native methods of {@link android.graphics.PathMeasure}
@@ -38,35 +40,30 @@
  * @see DelegateManager
  */
 public final class PathMeasure_Delegate {
+
     // ---- delegate manager ----
     private static final DelegateManager<PathMeasure_Delegate> sManager =
             new DelegateManager<PathMeasure_Delegate>(PathMeasure_Delegate.class);
 
     // ---- delegate data ----
-    // This governs how accurate the approximation of the Path is.
-    private static final float PRECISION = 0.0002f;
+    private CachedPathIteratorFactory mOriginalPathIterator;
 
-    /**
-     * Array containing the path points components. There are three components for each point:
-     * <ul>
-     *     <li>Fraction along the length of the path that the point resides</li>
-     *     <li>The x coordinate of the point</li>
-     *     <li>The y coordinate of the point</li>
-     * </ul>
-     */
-    private float mPathPoints[];
     private long mNativePath;
 
+
     private PathMeasure_Delegate(long native_path, boolean forceClosed) {
         mNativePath = native_path;
-        if (forceClosed && mNativePath != 0) {
-            // Copy the path and call close
-            mNativePath = Path_Delegate.init2(native_path);
-            Path_Delegate.native_close(mNativePath);
-        }
+        if (native_path != 0) {
+            if (forceClosed) {
+                // Copy the path and call close
+                native_path = Path_Delegate.init2(native_path);
+                Path_Delegate.native_close(native_path);
+            }
 
-        mPathPoints =
-                mNativePath != 0 ? Path_Delegate.native_approximate(mNativePath, PRECISION) : null;
+            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
+            mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
+                    .getPathIterator(null));
+        }
     }
 
     @LayoutlibDelegate
@@ -108,13 +105,19 @@
         PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
         assert pathMeasure != null;
 
-        if (forceClosed && native_path != 0) {
-            // Copy the path and call close
-            native_path = Path_Delegate.init2(native_path);
-            Path_Delegate.native_close(native_path);
+        if (native_path != 0) {
+            if (forceClosed) {
+                // Copy the path and call close
+                native_path = Path_Delegate.init2(native_path);
+                Path_Delegate.native_close(native_path);
+            }
+
+            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
+            pathMeasure.mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
+                    .getPathIterator(null));
         }
+
         pathMeasure.mNativePath = native_path;
-        pathMeasure.mPathPoints = Path_Delegate.native_approximate(native_path, PRECISION);
     }
 
     @LayoutlibDelegate
@@ -122,21 +125,11 @@
         PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
         assert pathMeasure != null;
 
-        if (pathMeasure.mPathPoints == null) {
+        if (pathMeasure.mOriginalPathIterator == null) {
             return 0;
         }
 
-        float length = 0;
-        int nPoints = pathMeasure.mPathPoints.length / 3;
-        for (int i = 1; i < nPoints; i++) {
-            length += Point2D.distance(
-                    pathMeasure.mPathPoints[(i - 1) * 3 + 1],
-                    pathMeasure.mPathPoints[(i - 1) * 3 + 2],
-                    pathMeasure.mPathPoints[i*3 + 1],
-                    pathMeasure.mPathPoints[i*3 + 2]);
-        }
-
-        return length;
+        return pathMeasure.mOriginalPathIterator.iterator().getTotalLength();
     }
 
     @LayoutlibDelegate
@@ -149,13 +142,10 @@
             return false;
         }
 
-        PathIterator pathIterator = path.getJavaShape().getPathIterator(null);
-
         int type = 0;
         float segment[] = new float[6];
-        while (!pathIterator.isDone()) {
-            type = pathIterator.currentSegment(segment);
-            pathIterator.next();
+        for (PathIterator pi = path.getJavaShape().getPathIterator(null); !pi.isDone(); pi.next()) {
+            type = pi.currentSegment(segment);
         }
 
         // A path is a closed path if the last element is SEG_CLOSE
@@ -176,33 +166,56 @@
         PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
         assert pathMeasure != null;
 
-        if (pathMeasure.mPathPoints == null) {
-            return false;
-        }
-
-        float accLength = 0;
+        CachedPathIterator iterator = pathMeasure.mOriginalPathIterator.iterator();
+        float accLength = startD;
         boolean isZeroLength = true; // Whether the output has zero length or not
-        int nPoints = pathMeasure.mPathPoints.length / 3;
-        for (int i = 0; i < nPoints; i++) {
-            float x = pathMeasure.mPathPoints[i * 3 + 1];
-            float y = pathMeasure.mPathPoints[i * 3 + 2];
-            if (accLength >= startD && accLength <= stopD) {
+        float[] points = new float[6];
+
+        iterator.jumpToSegment(accLength);
+        while (!iterator.isDone() && (stopD - accLength > 0.1f)) {
+            int type = iterator.currentSegment(points, stopD - accLength);
+
+            if (accLength - iterator.getCurrentSegmentLength() <= stopD) {
                 if (startWithMoveTo) {
                     startWithMoveTo = false;
-                    Path_Delegate.native_moveTo(native_dst_path, x, y);
-                } else {
-                    isZeroLength = false;
-                    Path_Delegate.native_lineTo(native_dst_path, x, y);
+
+                    // If this segment is a MOVETO, then we just use that one. If not, then we issue
+                    // a first moveto
+                    if (type != PathIterator.SEG_MOVETO) {
+                        float[] lastPoint = new float[2];
+                        iterator.getCurrentSegmentEnd(lastPoint);
+                        Path_Delegate.native_moveTo(native_dst_path, lastPoint[0], lastPoint[1]);
+                    }
+                }
+
+                isZeroLength = isZeroLength && iterator.getCurrentSegmentLength() > 0;
+                switch (type) {
+                    case PathIterator.SEG_MOVETO:
+                        Path_Delegate.native_moveTo(native_dst_path, points[0], points[1]);
+                        break;
+                    case PathIterator.SEG_LINETO:
+                        Path_Delegate.native_lineTo(native_dst_path, points[0], points[1]);
+                        break;
+                    case PathIterator.SEG_CLOSE:
+                        Path_Delegate.native_close(native_dst_path);
+                        break;
+                    case PathIterator.SEG_CUBICTO:
+                        Path_Delegate.native_cubicTo(native_dst_path, points[0], points[1],
+                                points[2], points[3],
+                                points[4], points[5]);
+                        break;
+                    case PathIterator.SEG_QUADTO:
+                        Path_Delegate.native_quadTo(native_dst_path, points[0], points[1],
+                                points[2],
+                                points[3]);
+                        break;
+                    default:
+                        assert false;
                 }
             }
 
-            if (i > 0) {
-                accLength += Point2D.distance(
-                        pathMeasure.mPathPoints[(i - 1) * 3 + 1],
-                        pathMeasure.mPathPoints[(i - 1) * 3 + 2],
-                        pathMeasure.mPathPoints[i * 3 + 1],
-                        pathMeasure.mPathPoints[i * 3 + 2]);
-            }
+            accLength += iterator.getCurrentSegmentLength();
+            iterator.next();
         }
 
         return !isZeroLength;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index a2a53fe..d0dd22f 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -57,6 +57,8 @@
     private static final DelegateManager<Path_Delegate> sManager =
             new DelegateManager<Path_Delegate>(Path_Delegate.class);
 
+    private static final float EPSILON = 1e-4f;
+
     // ---- delegate data ----
     private FillType mFillType = FillType.WINDING;
     private Path2D mPath = new Path2D.Double();
@@ -64,6 +66,9 @@
     private float mLastX = 0;
     private float mLastY = 0;
 
+    // true if the path contains does not contain a curve or line.
+    private boolean mCachedIsEmpty = true;
+
     // ---- Public Helper methods ----
 
     public static Path_Delegate getDelegate(long nPath) {
@@ -75,7 +80,7 @@
     }
 
     public void setJavaShape(Shape shape) {
-        mPath.reset();
+        reset();
         mPath.append(shape, false /*connect*/);
     }
 
@@ -84,7 +89,7 @@
     }
 
     public void setPathIterator(PathIterator iterator) {
-        mPath.reset();
+        reset();
         mPath.append(iterator, false /*connect*/);
     }
 
@@ -591,11 +596,37 @@
 
 
     /**
-     * Returns whether the path is empty.
-     * @return true if the path is empty.
+     * Returns whether the path already contains any points.
+     * Note that this is different to
+     * {@link #isEmpty} because if all elements are {@link PathIterator#SEG_MOVETO},
+     * {@link #isEmpty} will return true while hasPoints will return false.
      */
-    private boolean isEmpty() {
-        return mPath.getCurrentPoint() == null;
+    public boolean hasPoints() {
+        return !mPath.getPathIterator(null).isDone();
+    }
+
+    /**
+     * Returns whether the path is empty (contains no lines or curves).
+     * @see Path#isEmpty
+     */
+    public boolean isEmpty() {
+        if (!mCachedIsEmpty) {
+            return false;
+        }
+
+        float[] coords = new float[6];
+        mCachedIsEmpty = Boolean.TRUE;
+        for (PathIterator it = mPath.getPathIterator(null); !it.isDone(); it.next()) {
+            int type = it.currentSegment(coords);
+            if (type != PathIterator.SEG_MOVETO) {
+                // Once we know that the path is not empty, we do not need to check again unless
+                // Path#reset is called.
+                mCachedIsEmpty = false;
+                return false;
+            }
+        }
+
+        return true;
     }
 
     /**
@@ -645,7 +676,7 @@
      * @param y The y-coordinate of the end of a line
      */
     private void lineTo(float x, float y) {
-        if (isEmpty()) {
+        if (!hasPoints()) {
             mPath.moveTo(mLastX = 0, mLastY = 0);
         }
         mPath.lineTo(mLastX = x, mLastY = y);
@@ -662,9 +693,15 @@
      *           this contour, to specify a line
      */
     private void rLineTo(float dx, float dy) {
-        if (isEmpty()) {
+        if (!hasPoints()) {
             mPath.moveTo(mLastX = 0, mLastY = 0);
         }
+
+        if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON) {
+            // The delta is so small that this shouldn't generate a line
+            return;
+        }
+
         dx += mLastX;
         dy += mLastY;
         mPath.lineTo(mLastX = dx, mLastY = dy);
@@ -699,7 +736,7 @@
      *            this contour, for the end point of a quadratic curve
      */
     private void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
-        if (isEmpty()) {
+        if (!hasPoints()) {
             mPath.moveTo(mLastX = 0, mLastY = 0);
         }
         dx1 += mLastX;
@@ -723,7 +760,7 @@
      */
     private void cubicTo(float x1, float y1, float x2, float y2,
                         float x3, float y3) {
-        if (isEmpty()) {
+        if (!hasPoints()) {
             mPath.moveTo(0, 0);
         }
         mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
@@ -736,7 +773,7 @@
      */
     private void rCubicTo(float dx1, float dy1, float dx2, float dy2,
                          float dx3, float dy3) {
-        if (isEmpty()) {
+        if (!hasPoints()) {
             mPath.moveTo(mLastX = 0, mLastY = 0);
         }
         dx1 += mLastX;
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 01ee18b..9f0153a 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -19,6 +19,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import com.android.internal.app.IAssistScreenshotReceiver;
+import com.android.internal.os.IResultReceiver;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
 
@@ -550,4 +551,8 @@
     public void setResizeDimLayer(boolean visible, int targetStackId, float alpha)
             throws RemoteException {
     }
+
+    @Override
+    public void requestAppKeyboardShortcuts(IResultReceiver receiver) throws RemoteException {
+    }
 }
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/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
index d691c8e..411417c 100644
--- a/tools/layoutlib/bridge/src/android/view/WindowCallback.java
+++ b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
@@ -16,10 +16,13 @@
 
 package android.view;
 
+import android.annotation.Nullable;
 import android.view.ActionMode.Callback;
 import android.view.WindowManager.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 
+import java.util.List;
+
 /**
  * An empty implementation of {@link Window.Callback} that always returns null/false.
  */
@@ -138,4 +141,9 @@
     public void onActionModeFinished(ActionMode mode) {
 
     }
+
+    @Override
+    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, @Nullable Menu menu) {
+
+    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 63411b0..e6fb620 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -197,7 +197,12 @@
 
         mRenderResources = renderResources;
         mConfig = config;
-        mAssets = new BridgeAssetManager();
+        AssetManager systemAssetManager = AssetManager.getSystem();
+        if (systemAssetManager instanceof BridgeAssetManager) {
+            mAssets = (BridgeAssetManager) systemAssetManager;
+        } else {
+            throw new AssertionError("Creating BridgeContext without initializing Bridge");
+        }
         mAssets.setAssetRepository(assets);
 
         mApplicationInfo = new ApplicationInfo();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 3662573..48012db 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -16,6 +16,8 @@
 
 package com.android.layoutlib.bridge.android;
 
+import com.android.internal.os.IResultReceiver;
+
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -95,6 +97,10 @@
     }
 
     @Override
+    public void requestAppKeyboardShortcuts(IResultReceiver receiver) throws RemoteException {
+    }
+
+    @Override
     public IBinder asBinder() {
         // pass for now.
         return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 5c73fb6a..769285f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -89,7 +89,8 @@
     @Override
     public int relayout(IWindow iWindow, int i, LayoutParams layoutParams, int i2,
             int i3, int i4, int i5, Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5,
-            Rect rect6, Configuration configuration, Surface surface) throws RemoteException {
+            Rect rect6, Rect rect7, Configuration configuration, Surface surface)
+            throws RemoteException {
         // pass for now.
         return 0;
     }
@@ -230,4 +231,9 @@
     public void pokeDrawLock(IBinder window) {
         // pass for now.
     }
+
+    @Override
+    public void prepareToReplaceChildren(IBinder appToken) {
+        // pass for now.
+    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
index 7e5ae8d..d417eb7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
@@ -63,4 +63,9 @@
     public void removeViewImmediate(View arg0) {
         // pass
     }
+
+    @Override
+    public void requestAppKeyboardShortcuts(
+            KeyboardShortcutsReceiver receiver) {
+    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
index 9aab340..8c60bae 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
@@ -114,7 +114,7 @@
                         if (value != null) {
                             if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) {
                                 Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected Boolean, got %s",
+                                        "Wrong Adapter Item value class for IS_CHECKED. Expected Boolean, got %s",
                                         value.getClass().getName()), null);
                             } else {
                                 cb.setChecked((Boolean) value);
@@ -134,7 +134,7 @@
                         if (value != null) {
                             if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) {
                                 Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected Boolean, got %s",
+                                        "Wrong Adapter Item value class for SRC. Expected Boolean, got %s",
                                         value.getClass().getName()), null);
                             } else {
                                 // FIXME
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
new file mode 100644
index 0000000..0a9b9ec
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
@@ -0,0 +1,485 @@
+/*
+ * 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.layoutlib.bridge.util;
+
+import android.annotation.NonNull;
+
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+import java.util.ArrayList;
+
+import com.google.android.collect.Lists;
+
+/**
+ * Class that returns iterators for a given path. These iterators are lightweight and can be reused
+ * multiple times to iterate over the path.
+ */
+public class CachedPathIteratorFactory {
+    /*
+     * A few conventions used in the code:
+     * Coordinates or coords arrays store segment coordinates. They use the same format as
+     * PathIterator#currentSegment coordinates array.
+     * float arrays store always points where the first element is X and the second is Y.
+     */
+
+    // This governs how accurate the approximation of the Path is.
+    private static final float PRECISION = 0.002f;
+
+    private final int mWindingRule;
+    private final int[] mTypes;
+    private final float[][] mCoordinates;
+    private final float[] mSegmentsLength;
+    private final float mTotalLength;
+
+    public CachedPathIteratorFactory(@NonNull PathIterator iterator) {
+        mWindingRule = iterator.getWindingRule();
+
+        ArrayList<Integer> typesArray = Lists.newArrayList();
+        ArrayList<float[]> pointsArray = Lists.newArrayList();
+        float[] points = new float[6];
+        while (!iterator.isDone()) {
+            int type = iterator.currentSegment(points);
+            int nPoints = getNumberOfPoints(type) * 2; // 2 coordinates per point
+
+            typesArray.add(type);
+            float[] itemPoints = new float[nPoints];
+            System.arraycopy(points, 0, itemPoints, 0, nPoints);
+            pointsArray.add(itemPoints);
+            iterator.next();
+        }
+
+        mTypes = new int[typesArray.size()];
+        mCoordinates = new float[mTypes.length][];
+        for (int i = 0; i < typesArray.size(); i++) {
+            mTypes[i] = typesArray.get(i);
+            mCoordinates[i] = pointsArray.get(i);
+        }
+
+        // Do measurement
+        mSegmentsLength = new float[mTypes.length];
+
+        // Curves that we can reuse to estimate segments length
+        CubicCurve2D.Float cubicCurve = new CubicCurve2D.Float();
+        QuadCurve2D.Float quadCurve = new QuadCurve2D.Float();
+        float lastX = 0;
+        float lastY = 0;
+        float totalLength = 0;
+        for (int i = 0; i < mTypes.length; i++) {
+            switch (mTypes[i]) {
+                case PathIterator.SEG_CUBICTO:
+                    cubicCurve.setCurve(lastX, lastY,
+                            mCoordinates[i][0], mCoordinates[i][1], mCoordinates[i][2],
+                            mCoordinates[i][3], lastX = mCoordinates[i][4],
+                            lastY = mCoordinates[i][5]);
+                    mSegmentsLength[i] =
+                            getFlatPathLength(cubicCurve.getPathIterator(null, PRECISION));
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    quadCurve.setCurve(lastX, lastY, mCoordinates[i][0], mCoordinates[i][1],
+                            lastX = mCoordinates[i][2], lastY = mCoordinates[i][3]);
+                    mSegmentsLength[i] =
+                            getFlatPathLength(quadCurve.getPathIterator(null, PRECISION));
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY,
+                            lastX = mCoordinates[0][0],
+                            lastY = mCoordinates[0][1]);
+                    mCoordinates[i] = new float[2];
+                    // We convert a SEG_CLOSE segment to a SEG_LINETO so we do not have to worry
+                    // about this special case in the rest of the code.
+                    mTypes[i] = PathIterator.SEG_LINETO;
+                    mCoordinates[i][0] = mCoordinates[0][0];
+                    mCoordinates[i][1] = mCoordinates[0][1];
+                    break;
+                case PathIterator.SEG_MOVETO:
+                    mSegmentsLength[i] = 0;
+                    lastX = mCoordinates[i][0];
+                    lastY = mCoordinates[i][1];
+                    break;
+                case PathIterator.SEG_LINETO:
+                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY, mCoordinates[i][0],
+                            mCoordinates[i][1]);
+                    lastX = mCoordinates[i][0];
+                    lastY = mCoordinates[i][1];
+                default:
+            }
+            totalLength += mSegmentsLength[i];
+        }
+
+        mTotalLength = totalLength;
+    }
+
+    private static void quadCurveSegment(float[] coords, float t0, float t1) {
+        // Calculate X and Y at 0.5 (We'll use this to reconstruct the control point later)
+        float mt = t0 + (t1 - t0) / 2;
+        float mu = 1 - mt;
+        float mx = mu * mu * coords[0] + 2 * mu * mt * coords[2] + mt * mt * coords[4];
+        float my = mu * mu * coords[1] + 2 * mu * mt * coords[3] + mt * mt * coords[5];
+
+        float u0 = 1 - t0;
+        float u1 = 1 - t1;
+
+        // coords at t0
+        coords[0] = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
+        coords[1] = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
+
+        // coords at t1
+        coords[4] = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
+        coords[5] = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
+
+        // estimated control point at t'=0.5
+        coords[2] = 2 * mx - coords[0] / 2 - coords[4] / 2;
+        coords[3] = 2 * my - coords[1] / 2 - coords[5] / 2;
+    }
+
+    private static void cubicCurveSegment(float[] coords, float t0, float t1) {
+        // http://stackoverflow.com/questions/11703283/cubic-bezier-curve-segment
+        float u0 = 1 - t0;
+        float u1 = 1 - t1;
+
+        // Calculate the points at t0 and t1 for the quadratic curves formed by (P0, P1, P2) and
+        // (P1, P2, P3)
+        float qxa = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
+        float qxb = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
+        float qxc = coords[2] * u0 * u0 + coords[4] * 2 * t0 * u0 + coords[6] * t0 * t0;
+        float qxd = coords[2] * u1 * u1 + coords[4] * 2 * t1 * u1 + coords[6] * t1 * t1;
+
+        float qya = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
+        float qyb = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
+        float qyc = coords[3] * u0 * u0 + coords[5] * 2 * t0 * u0 + coords[7] * t0 * t0;
+        float qyd = coords[3] * u1 * u1 + coords[5] * 2 * t1 * u1 + coords[7] * t1 * t1;
+
+        // Linear interpolation
+        coords[0] = qxa * u0 + qxc * t0;
+        coords[1] = qya * u0 + qyc * t0;
+
+        coords[2] = qxa * u1 + qxc * t1;
+        coords[3] = qya * u1 + qyc * t1;
+
+        coords[4] = qxb * u0 + qxd * t0;
+        coords[5] = qyb * u0 + qyd * t0;
+
+        coords[6] = qxb * u1 + qxd * t1;
+        coords[7] = qyb * u1 + qyd * t1;
+    }
+
+    /**
+     * Returns the end point of a given segment
+     *
+     * @param type the segment type
+     * @param coords the segment coordinates array
+     * @param point the return array where the point will be stored
+     */
+    private static void getShapeEndPoint(int type, @NonNull float[] coords, @NonNull float[]
+            point) {
+        // start index of the end point for the segment type
+        int pointIndex = (getNumberOfPoints(type) - 1) * 2;
+        point[0] = coords[pointIndex];
+        point[1] = coords[pointIndex + 1];
+    }
+
+    /**
+     * Returns the number of points stored in a coordinates array for the given segment type.
+     */
+    private static int getNumberOfPoints(int segmentType) {
+        switch (segmentType) {
+            case PathIterator.SEG_QUADTO:
+                return 2;
+            case PathIterator.SEG_CUBICTO:
+                return 3;
+            case PathIterator.SEG_CLOSE:
+                return 0;
+            default:
+                return 1;
+        }
+    }
+
+    /**
+     * Returns the estimated length of a flat path. If the passed path is not flat (i.e. contains a
+     * segment that is not {@link PathIterator#SEG_CLOSE}, {@link PathIterator#SEG_MOVETO} or {@link
+     * PathIterator#SEG_LINETO} this method will fail.
+     */
+    private static float getFlatPathLength(@NonNull PathIterator iterator) {
+        float segment[] = new float[6];
+        float totalLength = 0;
+        float[] previousPoint = new float[2];
+        boolean isFirstPoint = true;
+
+        while (!iterator.isDone()) {
+            int type = iterator.currentSegment(segment);
+            assert type == PathIterator.SEG_LINETO || type == PathIterator.SEG_CLOSE || type ==
+                    PathIterator.SEG_MOVETO;
+
+            // MoveTo shouldn't affect the length
+            if (!isFirstPoint && type != PathIterator.SEG_MOVETO) {
+                totalLength += Point2D.distance(previousPoint[0], previousPoint[1], segment[0],
+                        segment[1]);
+            } else {
+                isFirstPoint = false;
+            }
+            previousPoint[0] = segment[0];
+            previousPoint[1] = segment[1];
+            iterator.next();
+        }
+
+        return totalLength;
+    }
+
+    /**
+     * Returns the estimated position along a path of the given length.
+     */
+    private void getPointAtLength(int type, @NonNull float[] coords, float lastX, float
+            lastY, float t, @NonNull float[] point) {
+        if (type == PathIterator.SEG_LINETO) {
+            point[0] = lastX + (coords[0] - lastX) * t;
+            point[1] = lastY + (coords[1] - lastY) * t;
+            // Return here, since we do not need a shape to estimate
+            return;
+        }
+
+        float[] curve = new float[8];
+        int lastPointIndex = (getNumberOfPoints(type) - 1) * 2;
+
+        System.arraycopy(coords, 0, curve, 2, coords.length);
+        curve[0] = lastX;
+        curve[1] = lastY;
+        if (type == PathIterator.SEG_CUBICTO) {
+            cubicCurveSegment(curve, 0f, t);
+        } else {
+            quadCurveSegment(curve, 0f, t);
+        }
+
+        point[0] = curve[2 + lastPointIndex];
+        point[1] = curve[2 + lastPointIndex + 1];
+    }
+
+    public CachedPathIterator iterator() {
+        return new CachedPathIterator();
+    }
+
+    /**
+     * Class that allows us to iterate over a path multiple times
+     */
+    public class CachedPathIterator implements PathIterator {
+        private int mNextIndex;
+
+        /**
+         * Current segment type.
+         *
+         * @see PathIterator
+         */
+        private int mCurrentType;
+
+        /**
+         * Stores the coordinates array of the current segment. The number of points stored depends
+         * on the segment type.
+         *
+         * @see PathIterator
+         */
+        private float[] mCurrentCoords = new float[6];
+        private float mCurrentSegmentLength;
+
+        /**
+         * Current segment length offset. When asking for the length of the current segment, the
+         * length will be reduced by this amount. This is useful when we are only using portions of
+         * the segment.
+         *
+         * @see #jumpToSegment(float)
+         */
+        private float mOffsetLength;
+
+        /** Point where the current segment started */
+        private float[] mLastPoint = new float[2];
+        private boolean isIteratorDone;
+
+        private CachedPathIterator() {
+            next();
+        }
+
+        public float getCurrentSegmentLength() {
+            return mCurrentSegmentLength;
+        }
+
+        @Override
+        public int getWindingRule() {
+            return mWindingRule;
+        }
+
+        @Override
+        public boolean isDone() {
+            return isIteratorDone;
+        }
+
+        @Override
+        public void next() {
+            if (mNextIndex >= mTypes.length) {
+                isIteratorDone = true;
+                return;
+            }
+
+            if (mNextIndex >= 1) {
+                // We've already called next() once so there is a previous segment in this path.
+                // We want to get the coordinates where the path ends.
+                getShapeEndPoint(mCurrentType, mCurrentCoords, mLastPoint);
+            } else {
+                // This is the first segment, no previous point so initialize to 0, 0
+                mLastPoint[0] = mLastPoint[1] = 0f;
+            }
+            mCurrentType = mTypes[mNextIndex];
+            mCurrentSegmentLength = mSegmentsLength[mNextIndex] - mOffsetLength;
+
+            if (mOffsetLength > 0f && (mCurrentType == SEG_CUBICTO || mCurrentType == SEG_QUADTO)) {
+                // We need to skip part of the start of the current segment (because
+                // mOffsetLength > 0)
+                float[] points = new float[8];
+
+                if (mNextIndex < 1) {
+                    points[0] = points[1] = 0f;
+                } else {
+                    getShapeEndPoint(mTypes[mNextIndex - 1], mCoordinates[mNextIndex - 1], points);
+                }
+
+                System.arraycopy(mCoordinates[mNextIndex], 0, points, 2,
+                        mCoordinates[mNextIndex].length);
+                float t0 = (mSegmentsLength[mNextIndex] - mCurrentSegmentLength) /
+                        mSegmentsLength[mNextIndex];
+                if (mCurrentType == SEG_CUBICTO) {
+                    cubicCurveSegment(points, t0, 1f);
+                } else {
+                    quadCurveSegment(points, t0, 1f);
+                }
+                System.arraycopy(points, 2, mCurrentCoords, 0, mCoordinates[mNextIndex].length);
+            } else {
+                System.arraycopy(mCoordinates[mNextIndex], 0, mCurrentCoords, 0,
+                        mCoordinates[mNextIndex].length);
+            }
+
+            mOffsetLength = 0f;
+            mNextIndex++;
+        }
+
+        @Override
+        public int currentSegment(float[] coords) {
+            System.arraycopy(mCurrentCoords, 0, coords, 0, getNumberOfPoints(mCurrentType) * 2);
+            return mCurrentType;
+        }
+
+        @Override
+        public int currentSegment(double[] coords) {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Returns the point where the current segment ends
+         */
+        public void getCurrentSegmentEnd(float[] point) {
+            point[0] = mLastPoint[0];
+            point[1] = mLastPoint[1];
+        }
+
+        /**
+         * Restarts the iterator and jumps all the segments of this path up to the length value.
+         */
+        public void jumpToSegment(float length) {
+            isIteratorDone = false;
+            if (length <= 0f) {
+                mNextIndex = 0;
+                return;
+            }
+
+            float accLength = 0;
+            float lastPoint[] = new float[2];
+            for (mNextIndex = 0; mNextIndex < mTypes.length; mNextIndex++) {
+                float segmentLength = mSegmentsLength[mNextIndex];
+                if (accLength + segmentLength >= length && mTypes[mNextIndex] != SEG_MOVETO) {
+                    float[] estimatedPoint = new float[2];
+                    getPointAtLength(mTypes[mNextIndex],
+                            mCoordinates[mNextIndex], lastPoint[0], lastPoint[1],
+                            (length - accLength) / segmentLength,
+                            estimatedPoint);
+
+                    // This segment makes us go further than length so we go back one step,
+                    // set a moveto and offset the length of the next segment by the length
+                    // of this segment that we've already used.
+                    mCurrentType = PathIterator.SEG_MOVETO;
+                    mCurrentCoords[0] = estimatedPoint[0];
+                    mCurrentCoords[1] = estimatedPoint[1];
+                    mCurrentSegmentLength = 0;
+
+                    // We need to offset next path length to account for the segment we've just
+                    // skipped.
+                    mOffsetLength = length - accLength;
+                    return;
+                }
+                accLength += segmentLength;
+                getShapeEndPoint(mTypes[mNextIndex], mCoordinates[mNextIndex], lastPoint);
+            }
+        }
+
+        /**
+         * Returns the current segment up to certain length. If the current segment is shorter than
+         * length, then the whole segment is returned. The segment coordinates are copied into the
+         * coords array.
+         *
+         * @return the segment type
+         */
+        public int currentSegment(@NonNull float[] coords, float length) {
+            int type = currentSegment(coords);
+            // If the length is greater than the current segment length, no need to find
+            // the cut point. Same if this is a SEG_MOVETO.
+            if (mCurrentSegmentLength <= length || type == SEG_MOVETO) {
+                return type;
+            }
+
+            float t = length / getCurrentSegmentLength();
+
+            // We find at which offset the end point is located within the coords array and set
+            // a new end point to cut the segment short
+            switch (type) {
+                case SEG_CUBICTO:
+                case SEG_QUADTO:
+                    float[] curve = new float[8];
+                    curve[0] = mLastPoint[0];
+                    curve[1] = mLastPoint[1];
+                    System.arraycopy(coords, 0, curve, 2, coords.length);
+                    if (type == SEG_CUBICTO) {
+                        cubicCurveSegment(curve, 0f, t);
+                    } else {
+                        quadCurveSegment(curve, 0f, t);
+                    }
+                    System.arraycopy(curve, 2, coords, 0, coords.length);
+                    break;
+                default:
+                    float[] point = new float[2];
+                    getPointAtLength(type, coords, mLastPoint[0], mLastPoint[1], t, point);
+                    coords[0] = point[0];
+                    coords[1] = point[1];
+            }
+
+            return type;
+        }
+
+        /**
+         * Returns the total length of the path
+         */
+        public float getTotalLength() {
+            return mTotalLength;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
new file mode 100644
index 0000000..72b87ab
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
new file mode 100644
index 0000000..ffc70dc
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="76dp"
+        android:width="76dp"
+        android:viewportHeight="48"
+        android:viewportWidth="48">
+
+    <group
+        android:name="root"
+        android:translateX="24.0"
+        android:translateY="24.0">
+        <!--
+            This is the same as the material indeterminate progressbar which involves drawing
+            several cubic segments
+        -->
+        <path
+            android:pathData="M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
+            android:strokeColor="#00FF00"
+            android:strokeLineCap="square"
+            android:strokeLineJoin="miter"
+            android:strokeWidth="1"
+            android:trimPathEnd="0.8"
+            android:trimPathStart="0.3" />
+        <!-- Same figure with reversed end and start -->
+        <path
+            android:pathData="M0, 0 m 0, -12 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
+            android:strokeColor="#FFFF00"
+            android:strokeLineCap="square"
+            android:strokeLineJoin="miter"
+            android:strokeWidth="1"
+            android:trimPathEnd="0.3"
+            android:trimPathStart="0.8" />
+
+        <!--
+            Draw a few partial quadratic segments
+        -->
+        <path
+            android:strokeWidth="2"
+            android:strokeColor="#FFFF00"
+            android:pathData="M2,2 Q 5 30 15 0"
+            android:trimPathStart="0.1"
+            android:trimPathEnd="0.9"
+        />
+
+        <!--
+            Draw a line
+        -->
+        <path
+            android:strokeWidth="3"
+            android:strokeColor="#00FFFF"
+            android:pathData="M-10,-10 L 10, 10"
+            android:trimPathStart="0.2"
+            android:trimPathEnd="0.8"
+        />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml
new file mode 100644
index 0000000..2ce4f4c
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/vector_drawable.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:padding="16dp"
+              android:orientation="horizontal"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent">
+    <ImageView
+             android:layout_height="fill_parent"
+             android:layout_width="fill_parent"
+             android:src="@drawable/multi_path" />
+
+</LinearLayout>
+
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index dea86bf..fe16a3e 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -355,7 +355,7 @@
         renderAndVerify(params, "expand_horz_layout.png");
     }
 
-    /** Test expand_layout.xml */
+    /** Test indeterminate_progressbar.xml */
     @Test
     public void testVectorAnimation() throws ClassNotFoundException {
         // Create the layout pull parser.
@@ -380,10 +380,31 @@
     }
 
     /**
-     * Create a new rendering session and test that rendering given layout on nexus 5
-     * doesn't throw any exceptions and matches the provided image.
-     * <p/>If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time
-     * indicates how far in the future is.
+     * Test a vector drawable that uses trimStart and trimEnd. It also tests all the primitives
+     * for vector drawables (lines, moves and cubic and quadratic curves).
+     */
+    @Test
+    public void testVectorDrawable() throws ClassNotFoundException {
+        // Create the layout pull parser.
+        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
+                "vector_drawable.xml");
+        // Create LayoutLibCallback.
+        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        layoutLibCallback.initResources();
+
+        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
+                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
+                RenderingMode.V_SCROLL, 22);
+
+        renderAndVerify(params, "vector_drawable.png", TimeUnit.SECONDS.toNanos(2));
+    }
+
+    /**
+     * Create a new rendering session and test that rendering the given layout doesn't throw any
+     * exceptions and matches the provided image.
+     * <p>
+     * If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time indicates
+     * how far in the future is.
      */
     private void renderAndVerify(SessionParams params, String goldenFileName, long frameTimeNanos)
             throws ClassNotFoundException {
@@ -414,8 +435,8 @@
     }
 
     /**
-     * Create a new rendering session and test that rendering given layout on nexus 5
-     * doesn't throw any exceptions and matches the provided image.
+     * Create a new rendering session and test that rendering the given layout doesn't throw any
+     * exceptions and matches the provided image.
      */
     private void renderAndVerify(SessionParams params, String goldenFileName)
             throws ClassNotFoundException {
@@ -423,7 +444,7 @@
     }
 
     /**
-     * Create a new rendering session and test that rendering given layout on nexus 5
+     * Create a new rendering session and test that rendering the given layout on nexus 5
      * doesn't throw any exceptions and matches the provided image.
      */
     private void renderAndVerify(String layoutFileName, String goldenFileName)
@@ -432,7 +453,7 @@
     }
 
     /**
-     * Create a new rendering session and test that rendering given layout on given device
+     * Create a new rendering session and test that rendering the given layout on given device
      * doesn't throw any exceptions and matches the provided image.
      */
     private void renderAndVerify(String layoutFileName, String goldenFileName,
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/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index dc329e2..274e985 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -24,15 +24,12 @@
 import android.net.StaticIpConfiguration;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.text.TextUtils;
-import android.util.Log;
 
-import java.util.HashMap;
+import java.util.Arrays;
 import java.util.BitSet;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
+import java.util.HashMap;
 
 /**
  * A class representing a configured Wi-Fi network, including the
@@ -81,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";
@@ -182,19 +180,6 @@
     }
 
     /** @hide */
-    public static final int DISABLED_UNKNOWN_REASON                         = 0;
-    /** @hide */
-    public static final int DISABLED_DNS_FAILURE                            = 1;
-    /** @hide */
-    public static final int DISABLED_DHCP_FAILURE                           = 2;
-    /** @hide */
-    public static final int DISABLED_AUTH_FAILURE                           = 3;
-    /** @hide */
-    public static final int DISABLED_ASSOCIATION_REJECT                     = 4;
-    /** @hide */
-    public static final int DISABLED_BY_WIFI_MANAGER                        = 5;
-
-    /** @hide */
     public static final int UNKNOWN_UID = -1;
 
     /**
@@ -206,24 +191,12 @@
 
     /**
      * The current status of this network configuration entry.
+     * Fixme We need remove this field to use only Quality network selection status only
      * @see Status
      */
     public int status;
 
     /**
-     * The configuration needs to be written to networkHistory.txt
-     * @hide
-     */
-    public boolean dirty;
-
-    /**
-     * The code referring to a reason for disabling the network
-     * Valid when {@link #status} == Status.DISABLED
-     * @hide
-     */
-    public int disableReason;
-
-    /**
      * The network's SSID. Can either be an ASCII string,
      * which must be enclosed in double quotation marks
      * (e.g., {@code "MyNetwork"}, or a string of
@@ -356,6 +329,13 @@
 
     /**
      * @hide
+     * This network configuration is visible to and usable by other users on the
+     * same device.
+     */
+    public boolean shared;
+
+    /**
+     * @hide
      */
     private IpConfiguration mIpConfiguration;
 
@@ -421,12 +401,6 @@
 
     /**
      * @hide
-     * Uid used by autoJoin
-     */
-    public String autoJoinBSSID;
-
-    /**
-     * @hide
      * Status of user approval for connection
      */
     public int userApproved = USER_UNSPECIFIED;
@@ -444,77 +418,6 @@
     /** @hide **/
     public static int INVALID_RSSI = -127;
 
-    /** @hide **/
-    public static int UNWANTED_BLACKLIST_SOFT_RSSI_24 = -80;
-
-    /** @hide **/
-    public static int UNWANTED_BLACKLIST_SOFT_RSSI_5 = -70;
-
-    /** @hide **/
-    public static int GOOD_RSSI_24 = -65;
-
-    /** @hide **/
-    public static int LOW_RSSI_24 = -77;
-
-    /** @hide **/
-    public static int BAD_RSSI_24 = -87;
-
-    /** @hide **/
-    public static int GOOD_RSSI_5 = -60;
-
-    /** @hide **/
-    public static int LOW_RSSI_5 = -72;
-
-    /** @hide **/
-    public static int BAD_RSSI_5 = -82;
-
-    /** @hide **/
-    public static int UNWANTED_BLACKLIST_SOFT_BUMP = 4;
-
-    /** @hide **/
-    public static int UNWANTED_BLACKLIST_HARD_BUMP = 8;
-
-    /** @hide **/
-    public static int UNBLACKLIST_THRESHOLD_24_SOFT = -77;
-
-    /** @hide **/
-    public static int UNBLACKLIST_THRESHOLD_24_HARD = -68;
-
-    /** @hide **/
-    public static int UNBLACKLIST_THRESHOLD_5_SOFT = -63;
-
-    /** @hide **/
-    public static int UNBLACKLIST_THRESHOLD_5_HARD = -56;
-
-    /** @hide **/
-    public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_24 = -80;
-
-    /** @hide **/
-    public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_5 = -70;
-
-    /** @hide
-     * 5GHz band is prefered low over 2.4 if the 5GHz RSSI is higher than this threshold */
-    public static int A_BAND_PREFERENCE_RSSI_THRESHOLD = -65;
-
-    /** @hide
-     * 5GHz band is penalized if the 5GHz RSSI is lower than this threshold **/
-    public static int G_BAND_PREFERENCE_RSSI_THRESHOLD = -75;
-
-    /** @hide
-     * Boost given to RSSI on a home network for the purpose of calculating the score
-     * This adds stickiness to home networks, as defined by:
-     * - less than 4 known BSSIDs
-     * - PSK only
-     * - TODO: add a test to verify that all BSSIDs are behind same gateway
-     ***/
-    public static int HOME_NETWORK_RSSI_BOOST = 5;
-
-    /** @hide
-     * RSSI boost for configuration which use autoJoinUseAggressiveJoinAttemptThreshold
-     * To be more aggressive when initially attempting to auto join
-     */
-    public static int MAX_INITIAL_AUTO_JOIN_RSSI_BOOST = 8;
-
     /**
      * @hide
      * A summary of the RSSI and Band status for that configuration
@@ -600,38 +503,6 @@
         visibility = status;
     }
 
-    /** @hide */
-    public static final int AUTO_JOIN_ENABLED                   = 0;
-    /**
-     * if this is set, the WifiConfiguration cannot use linkages so as to bump
-     * it's relative priority.
-     * - status between and 128 indicate various level of blacklisting depending
-     * on the severity or frequency of the connection error
-     * - deleted status indicates that the user is deleting the configuration, and so
-     * although it may have been self added we will not re-self-add it, ignore it,
-     * not return it to applications, and not connect to it
-     * */
-
-    /** @hide
-     * network was temporary disabled due to bad connection, most likely due
-     * to weak RSSI */
-    public static final int AUTO_JOIN_TEMPORARY_DISABLED  = 1;
-    /** @hide
-     * network was temporary disabled due to bad connection, which cant be attributed
-     * to weak RSSI */
-    public static final int AUTO_JOIN_TEMPORARY_DISABLED_LINK_ERRORS  = 32;
-    /** @hide */
-    public static final int AUTO_JOIN_TEMPORARY_DISABLED_AT_SUPPLICANT  = 64;
-    /** @hide */
-    public static final int AUTO_JOIN_DISABLED_ON_AUTH_FAILURE  = 128;
-    /** @hide */
-    public static final int AUTO_JOIN_DISABLED_NO_CREDENTIALS = 160;
-    /** @hide */
-    public static final int AUTO_JOIN_DISABLED_USER_ACTION = 161;
-
-    /** @hide */
-    public static final int AUTO_JOIN_DELETED  = 200;
-
     // States for the userApproved field
     /**
      * @hide
@@ -656,29 +527,6 @@
 
     /**
      * @hide
-     */
-    public int autoJoinStatus;
-
-    /**
-     * @hide
-     * Number of connection failures
-     */
-    public int numConnectionFailures;
-
-    /**
-     * @hide
-     * Number of IP config failures
-     */
-    public int numIpConfigFailures;
-
-    /**
-     * @hide
-     * Number of Auth failures
-     */
-    public int numAuthFailures;
-
-    /**
-     * @hide
      * Number of reports indicating no Internet Access
      */
     public int numNoInternetAccessReports;
@@ -715,12 +563,6 @@
 
     /**
      * @hide
-     * Last time we blacklisted the configuration
-     */
-    public long blackListTimestamp;
-
-    /**
-     * @hide
      * Last time the system was connected to this configuration.
      */
     public long lastConnected;
@@ -795,18 +637,6 @@
 
     /**
      * @hide
-     * Indicate that we didn't auto-join because rssi was too low
-     */
-    public boolean autoJoinBailedDueToLowRssi;
-
-    /**
-     * @hide
-     * AutoJoin even though RSSI is 10dB below threshold
-     */
-    public int autoJoinUseAggressiveJoinAttemptThreshold;
-
-    /**
-     * @hide
      * Number of time the scorer overrode a the priority based choice, when comparing two
      * WifiConfigurations, note that since comparing WifiConfiguration happens very often
      * potentially at every scan, this number might become very large, even on an idle
@@ -892,6 +722,365 @@
      */
     public HashMap<String, Integer> connectChoices;
 
+    /** @hide
+     * Boost given to RSSI on a home network for the purpose of calculating the score
+     * This adds stickiness to home networks, as defined by:
+     * - less than 4 known BSSIDs
+     * - PSK only
+     * - TODO: add a test to verify that all BSSIDs are behind same gateway
+     ***/
+    public static final int HOME_NETWORK_RSSI_BOOST = 5;
+
+    /**
+     * @hide
+     * This class is used to contain all the information and API used for quality network selection
+     */
+    public static class NetworkSelectionStatus {
+        /**
+         * Quality Network Selection Status enable, temporary disabled, permanently disabled
+         */
+        /**
+         * This network is allowed to join Quality Network Selection
+         */
+        public static final int NETWORK_SELECTION_ENABLED = 0;
+        /**
+         * network was temporary disabled. Can be re-enabled after a time period expire
+         */
+        public static final int NETWORK_SELECTION_TEMPORARY_DISABLED  = 1;
+        /**
+         * network was permanently disabled.
+         */
+        public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED  = 2;
+        /**
+         * Maximum Network selection status
+         */
+        public static final int NETWORK_SELECTION_STATUS_MAX = 3;
+
+        /**
+         * Quality network selection status String (for debug purpose). Use Quality network
+         * 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_PERMANENTLY_DISABLED"};
+
+        //Quality Network disabled reasons
+        /**
+         * Default value. Means not disabled
+         */
+        public static final int NETWORK_SELECTION_ENABLE = 0;
+        /**
+         * This network is disabled because higher layer (>2) network is bad
+         */
+        public static final int DISABLED_BAD_LINK = 1;
+        /**
+         * This network is disabled because multiple association rejects
+         */
+        public static final int DISABLED_ASSOCIATION_REJECTION = 2;
+        /**
+         * This network is disabled because multiple authentication failure
+         */
+        public static final int DISABLED_AUTHENTICATION_FAILURE = 3;
+        /**
+         * This network is disabled because multiple DHCP failure
+         */
+        public static final int DISABLED_DHCP_FAILURE = 4;
+        /**
+         * This network is disabled because of security network but no credentials
+         */
+        public static final int DISABLED_DNS_FAILURE = 5;
+        /**
+         * This network is disabled because EAP-TLS failure
+         */
+        public static final int DISABLED_TLS_VERSION_MISMATCH = 6;
+        /**
+         * This network is disabled due to WifiManager disable it explicitly
+         */
+        public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 7;
+        /**
+         * This network is disabled because no Internet connected and user do not want
+         */
+        public static final int DISABLED_NO_INTERNET = 8;
+        /**
+         * This network is disabled due to WifiManager disable it explicitly
+         */
+        public static final int DISABLED_BY_WIFI_MANAGER = 9;
+        /**
+         * This Maximum disable reason value
+         */
+        public static final int NETWORK_SELECTION_DISABLED_MAX = 10;
+
+        /**
+         * 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_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_AUTHENTICATION_NO_CREDENTIALS",
+                "NETWORK_SELECTION_DISABLED_NO_INTERNET",
+                "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER"};
+
+        /**
+         * Invalid time stamp for network selection disable
+         */
+        public static final long INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP = -1L;
+
+        // fields for QualityNetwork Selection
+        /**
+         * Network selection status, should be in one of three status: enable, temporaily disabled
+         * or permanently disabled
+         */
+        private int mStatus;
+
+        /**
+         * Reason for disable this network
+         */
+        private int mNetworkSelectionDisableReason;
+
+        /**
+         * Last time we temporarily disabled the configuration
+         */
+        private long mTemporarilyDisabledTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP;
+
+        /**
+         * counter for each Network selection disable reason
+         */
+        private int[] mNetworkSeclectionDisableCounter = new int[NETWORK_SELECTION_DISABLED_MAX];
+
+        /**
+         * return current Quality network selection status in String (for debug purpose)
+         */
+        public String getNetworkStatusString() {
+            return QUALITY_NETWORK_SELECTION_STATUS[mStatus];
+        }
+
+        private NetworkSelectionStatus() {};
+
+        /**
+         * @param reason specific error reason
+         * @return  corresponding network disable reason String (for debug purpose)
+         */
+        public static String getNetworkDisableReasonString(int reason) {
+            if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
+                return QUALITY_NETWORK_SELECTION_DISABLE_REASON[reason];
+            } else {
+                return null;
+            }
+        }
+        /**
+         * @return current network disable reason in String (for debug purpose)
+         */
+        public String getNetworkDisableReasonString() {
+            return QUALITY_NETWORK_SELECTION_DISABLE_REASON[mNetworkSelectionDisableReason];
+        }
+
+        /**
+         * get current network network selection status
+         */
+        public int getNetworkSelectionStatus() {
+            return mStatus;
+        }
+        /**
+         * @return whether current network is enabled to join network selection
+         */
+        public boolean isNetworkEnabled() {
+            return mStatus == NETWORK_SELECTION_ENABLED;
+        }
+
+        /**
+         * @return whether current network is temporary disabled
+         */
+        public boolean isNetworkTemporaryDisabled() {
+            return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED;
+        }
+
+        /**
+         * return whether current network is permanently disabled
+         */
+        public boolean isNetworkPermanentlyDisabled() {
+            return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED;
+        }
+        /**
+         * @param status network selection status to set
+         */
+        public void setNetworkSelectionStatus(int status) {
+            if (status >= 0 && status < NETWORK_SELECTION_STATUS_MAX) {
+                mStatus = status;
+            }
+        }
+        /**
+         * @return current network's disable reason
+         */
+        public int getNetworkSelectionDisableReason() {
+            return mNetworkSelectionDisableReason;
+        }
+
+        /**
+         * @param  reason Network disable reason
+         */
+        public void setNetworkSelectionDisableReason(int reason) {
+            if (reason >= 0 && reason < NETWORK_SELECTION_DISABLED_MAX) {
+                mNetworkSelectionDisableReason = reason;
+            } else {
+                throw new IllegalArgumentException("Illegal reason value: " + reason);
+            }
+        }
+        /**
+         * @param reason whether current network is disabled by this reason
+         */
+        public boolean isDisabledByReason(int reason) {
+            return mNetworkSelectionDisableReason == reason;
+        }
+        /**
+         * @param timeStamp Set when current network is disabled in millisecond since January 1,
+         * 1970 00:00:00.0 UTC
+         */
+        public void setDisableTime(long timeStamp) {
+            mTemporarilyDisabledTimestamp = timeStamp;
+        }
+
+        /**
+         * @return Get when current network is disabled in millisecond since January 1,
+         * 1970 00:00:00.0 UTC
+         */
+        public long getDisableTime() {
+            return mTemporarilyDisabledTimestamp;
+        }
+
+        /**
+         * @param  reason specific failure reason
+         * @exception throw IllegalArgumentException for illegal input
+         * @return counter number for specific error reason.
+         */
+        public int getDisableReasonCounter(int reason) {
+            if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
+                return mNetworkSeclectionDisableCounter[reason];
+            } else {
+                throw new IllegalArgumentException("Illegal reason value: " + reason);
+            }
+        }
+
+        /**
+         * set the counter of a specific failure reason
+         * @param reason reason for disable error
+         * @param value the counter value for this specific reason
+         * @exception throw IllegalArgumentException for illegal input
+         */
+        public void setDisableReasonCounter(int reason, int value) {
+            if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
+                mNetworkSeclectionDisableCounter[reason] = value;
+            } else {
+                throw new IllegalArgumentException("Illegal reason value: " + reason);
+            }
+        }
+
+        /**
+         * increment the counter of a specific failure reason
+         * @param reason a specific failure reason
+         * @exception throw IllegalArgumentException for illegal input
+         */
+        public void incrementDisableReasonCounter(int reason) {
+            if (reason >= NETWORK_SELECTION_ENABLE  && reason < NETWORK_SELECTION_DISABLED_MAX) {
+                mNetworkSeclectionDisableCounter[reason]++;
+            } else {
+                throw new IllegalArgumentException("Illegal reason value: " + reason);
+            }
+        }
+        /**
+         * clear the counter of a specific failure reason
+         * @hide
+         * @param reason a specific failure reason
+         * @exception throw IllegalArgumentException for illegal input
+         */
+        public void clearDisableReasonCounter(int reason) {
+            if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
+                mNetworkSeclectionDisableCounter[reason] = NETWORK_SELECTION_ENABLE;
+            } else {
+                throw new IllegalArgumentException("Illegal reason value: " + reason);
+            }
+        }
+        /**
+         * clear all the failure reason counters
+         */
+        public void clearDisableReasonCounter() {
+            Arrays.fill(mNetworkSeclectionDisableCounter, NETWORK_SELECTION_ENABLE);
+        }
+
+        /**
+         * BSSID for connection to this network (through network selection procedure)
+         */
+        private String mNetworkSelectionBSSID;
+
+        /**
+         * get current network Selection BSSID
+         * @return current network Selection BSSID
+         */
+        public String getNetworkSelectionBSSID() {
+            return mNetworkSelectionBSSID;
+        }
+
+        /**
+         * set network Selection BSSID
+         * @param bssid The target BSSID for assocaition
+         */
+        public void setNetworkSelectionBSSID(String bssid) {
+            mNetworkSelectionBSSID = bssid;
+        }
+
+        public void copy(NetworkSelectionStatus source) {
+            mStatus = source.mStatus;
+            mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason;
+            for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX;
+                    index++) {
+                mNetworkSeclectionDisableCounter[index] =
+                        source.mNetworkSeclectionDisableCounter[index];
+            }
+            mTemporarilyDisabledTimestamp = source.mTemporarilyDisabledTimestamp;
+            mNetworkSelectionBSSID = source.mNetworkSelectionBSSID;
+        }
+
+        public void writeToParcel(Parcel dest) {
+            dest.writeInt(getNetworkSelectionStatus());
+            dest.writeInt(getNetworkSelectionDisableReason());
+            for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX;
+                    index++) {
+                dest.writeInt(getDisableReasonCounter(index));
+            }
+            dest.writeLong(getDisableTime());
+            dest.writeString(getNetworkSelectionBSSID());
+        }
+
+        public void readFromParcel(Parcel in) {
+            setNetworkSelectionStatus(in.readInt());
+            setNetworkSelectionDisableReason(in.readInt());
+            for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX;
+                    index++) {
+                setDisableReasonCounter(index, in.readInt());
+            }
+            setDisableTime(in.readLong());
+            setNetworkSelectionBSSID(in.readString());
+        }
+    }
+
+    /**
+     * @hide
+     * network selection related member
+     */
+    private final NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus();
+
+    /**
+     * @hide
+     * @return network selection status
+     */
+    public NetworkSelectionStatus getNetworkSelectionStatus() {
+        return mNetworkSelectionStatus;
+    }
     /**
      * @hide
      * Linked Configurations: represent the set of Wificonfigurations that are equivalent
@@ -910,7 +1099,6 @@
         roamingConsortiumIds = new long[0];
         priority = 0;
         hiddenSSID = false;
-        disableReason = DISABLED_UNKNOWN_REASON;
         allowedKeyManagement = new BitSet();
         allowedProtocols = new BitSet();
         allowedAuthAlgorithms = new BitSet();
@@ -921,7 +1109,6 @@
             wepKeys[i] = null;
         }
         enterpriseConfig = new WifiEnterpriseConfig();
-        autoJoinStatus = AUTO_JOIN_ENABLED;
         selfAdded = false;
         didSelfAdd = false;
         ephemeral = false;
@@ -929,6 +1116,7 @@
         mIpConfiguration = new IpConfiguration();
         lastUpdateUid = -1;
         creatorUid = -1;
+        shared = true;
     }
 
     /**
@@ -946,10 +1134,12 @@
      * @hide
      */
     public boolean isLinked(WifiConfiguration config) {
-        if (config.linkedConfigurations != null && linkedConfigurations != null) {
-            if (config.linkedConfigurations.get(configKey()) != null
-                    && linkedConfigurations.get(config.configKey()) != null) {
-                return true;
+        if (config != null) {
+            if (config.linkedConfigurations != null && linkedConfigurations != null) {
+                if (config.linkedConfigurations.get(configKey()) != null
+                        && linkedConfigurations.get(config.configKey()) != null) {
+                    return true;
+                }
             }
         }
         return  false;
@@ -964,20 +1154,6 @@
             allowedKeyManagement.get(KeyMgmt.IEEE8021X);
     }
 
-    /** @hide **/
-    public void setAutoJoinStatus(int status) {
-        if (status < 0) status = 0;
-        if (status == 0) {
-            blackListTimestamp = 0;
-        }  else if (status > autoJoinStatus) {
-            blackListTimestamp = System.currentTimeMillis();
-        }
-        if (status != autoJoinStatus) {
-            autoJoinStatus = status;
-            dirty = true;
-        }
-    }
-
     @Override
     public String toString() {
         StringBuilder sbuf = new StringBuilder();
@@ -988,24 +1164,28 @@
         }
         sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).
                 append(" PROVIDER-NAME: ").append(this.providerFriendlyName).
-                append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN).
-                append(" PRIO: ").append(this.priority).
-                append('\n');
-        if (this.numConnectionFailures > 0) {
-            sbuf.append(" numConnectFailures ").append(this.numConnectionFailures).append("\n");
+                append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN)
+                .append(" PRIO: ").append(this.priority)
+                .append('\n');
+
+
+        sbuf.append(" NetworkSelectionStatus ")
+                .append(mNetworkSelectionStatus.getNetworkStatusString() + "\n");
+        if (mNetworkSelectionStatus.getNetworkSelectionDisableReason() > 0) {
+            sbuf.append(" mNetworkSelectionDisableReason ")
+                    .append(mNetworkSelectionStatus.getNetworkDisableReasonString() + "\n");
+
+            for (int index = mNetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
+                    index < mNetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) {
+                if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) {
+                    sbuf.append(NetworkSelectionStatus.getNetworkDisableReasonString(index)
+                            + " counter:" + mNetworkSelectionStatus.getDisableReasonCounter(index)
+                            + "\n");
+                }
+            }
         }
-        if (this.numIpConfigFailures > 0) {
-            sbuf.append(" numIpConfigFailures ").append(this.numIpConfigFailures).append("\n");
-        }
-        if (this.numAuthFailures > 0) {
-            sbuf.append(" numAuthFailures ").append(this.numAuthFailures).append("\n");
-        }
-        if (this.autoJoinStatus > 0) {
-            sbuf.append(" autoJoinStatus ").append(this.autoJoinStatus).append("\n");
-        }
-        if (this.disableReason > 0) {
-            sbuf.append(" disableReason ").append(this.disableReason).append("\n");
-        }
+
+
         if (this.numAssociation > 0) {
             sbuf.append(" numAssociation ").append(this.numAssociation).append("\n");
         }
@@ -1094,11 +1274,15 @@
         sbuf.append("IP config:\n");
         sbuf.append(mIpConfiguration.toString());
 
-        if (this.autoJoinBSSID != null) sbuf.append(" autoJoinBSSID=" + autoJoinBSSID);
+        if (mNetworkSelectionStatus.getNetworkSelectionBSSID() != null) {
+            sbuf.append(" networkSelectionBSSID="
+                    + mNetworkSelectionStatus.getNetworkSelectionBSSID());
+        }
         long now_ms = System.currentTimeMillis();
-        if (this.blackListTimestamp != 0) {
+        if (mNetworkSelectionStatus.getDisableTime() != NetworkSelectionStatus
+                .INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP) {
             sbuf.append('\n');
-            long diff = now_ms - this.blackListTimestamp;
+            long diff = now_ms - mNetworkSelectionStatus.getDisableTime();
             if (diff <= 0) {
                 sbuf.append(" blackListed since <incorrect>");
             } else {
@@ -1172,11 +1356,6 @@
         sbuf.append('\n');
         sbuf.append("triggeredJoin: ").append(this.numUserTriggeredJoinAttempts);
         sbuf.append('\n');
-        sbuf.append("autoJoinBailedDueToLowRssi: ").append(this.autoJoinBailedDueToLowRssi);
-        sbuf.append('\n');
-        sbuf.append("autoJoinUseAggressiveJoinAttemptThreshold: ");
-        sbuf.append(this.autoJoinUseAggressiveJoinAttemptThreshold);
-        sbuf.append('\n');
 
         return sbuf.toString();
     }
@@ -1323,6 +1502,9 @@
             key = mCachedConfigKey;
         } else if (providerFriendlyName != null) {
             key = FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP];
+            if (!shared) {
+                key += "-" + Integer.toString(UserHandle.getUserId(creatorUid));
+            }
         } else {
             if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
                 key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
@@ -1334,6 +1516,9 @@
             } else {
                 key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
             }
+            if (!shared) {
+                key += "-" + Integer.toString(UserHandle.getUserId(creatorUid));
+            }
             mCachedConfigKey = key;
         }
         return key;
@@ -1346,27 +1531,6 @@
         return configKey(false);
     }
 
-    /** @hide
-     * return the config key string based on a scan result
-     */
-    static public String configKey(ScanResult result) {
-        String key = "\"" + result.SSID + "\"";
-
-        if (result.capabilities.contains("WEP")) {
-            key = key + "-WEP";
-        }
-
-        if (result.capabilities.contains("PSK")) {
-            key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_PSK];
-        }
-
-        if (result.capabilities.contains("EAP")) {
-            key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_EAP];
-        }
-
-        return key;
-    }
-
     /** @hide */
     public IpConfiguration getIpConfiguration() {
         return mIpConfiguration;
@@ -1428,13 +1592,16 @@
         return 0;
     }
 
+    /** @hide */
+    public boolean isVisibleToUser(int userId) {
+        return shared || (UserHandle.getUserId(creatorUid) == userId);
+    }
+
     /** copy constructor {@hide} */
     public WifiConfiguration(WifiConfiguration source) {
         if (source != null) {
             networkId = source.networkId;
             status = source.status;
-            disableReason = source.disableReason;
-            disableReason = source.disableReason;
             SSID = source.SSID;
             BSSID = source.BSSID;
             FQDN = source.FQDN;
@@ -1442,6 +1609,7 @@
             providerFriendlyName = source.providerFriendlyName;
             preSharedKey = source.preSharedKey;
 
+            mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus());
             apBand = source.apBand;
             apChannel = source.apChannel;
 
@@ -1458,7 +1626,6 @@
             allowedAuthAlgorithms  = (BitSet) source.allowedAuthAlgorithms.clone();
             allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();
             allowedGroupCiphers    = (BitSet) source.allowedGroupCiphers.clone();
-
             enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig);
 
             defaultGwMacAddress = source.defaultGwMacAddress;
@@ -1476,7 +1643,6 @@
                 linkedConfigurations.putAll(source.linkedConfigurations);
             }
             mCachedConfigKey = null; //force null configKey
-            autoJoinStatus = source.autoJoinStatus;
             selfAdded = source.selfAdded;
             validatedInternetAccess = source.validatedInternetAccess;
             ephemeral = source.ephemeral;
@@ -1492,16 +1658,13 @@
             creatorName = source.creatorName;
             lastUpdateName = source.lastUpdateName;
             peerWifiConfiguration = source.peerWifiConfiguration;
-            blackListTimestamp = source.blackListTimestamp;
+
             lastConnected = source.lastConnected;
             lastDisconnected = source.lastDisconnected;
             lastConnectionFailure = source.lastConnectionFailure;
             lastRoamingFailure = source.lastRoamingFailure;
             lastRoamingFailureReason = source.lastRoamingFailureReason;
             roamingFailureBlackListTimeMilli = source.roamingFailureBlackListTimeMilli;
-            numConnectionFailures = source.numConnectionFailures;
-            numIpConfigFailures = source.numIpConfigFailures;
-            numAuthFailures = source.numAuthFailures;
             numScorerOverride = source.numScorerOverride;
             numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
             numAssociation = source.numAssociation;
@@ -1512,16 +1675,12 @@
             numTicksAtBadRSSI = source.numTicksAtBadRSSI;
             numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI;
             numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts;
-            autoJoinBSSID = source.autoJoinBSSID;
-            autoJoinUseAggressiveJoinAttemptThreshold
-                    = source.autoJoinUseAggressiveJoinAttemptThreshold;
-            autoJoinBailedDueToLowRssi = source.autoJoinBailedDueToLowRssi;
-            dirty = source.dirty;
             userApproved = source.userApproved;
             numNoInternetAccessReports = source.numNoInternetAccessReports;
             noInternetAccessExpected = source.noInternetAccessExpected;
             creationTime = source.creationTime;
             updateTime = source.updateTime;
+            shared = source.shared;
         }
     }
 
@@ -1535,12 +1694,11 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(networkId);
         dest.writeInt(status);
-        dest.writeInt(disableReason);
+        mNetworkSelectionStatus.writeToParcel(dest);
         dest.writeString(SSID);
         dest.writeString(BSSID);
         dest.writeInt(apBand);
         dest.writeInt(apChannel);
-        dest.writeString(autoJoinBSSID);
         dest.writeString(FQDN);
         dest.writeString(providerFriendlyName);
         dest.writeInt(roamingConsortiumIds.length);
@@ -1568,7 +1726,6 @@
         dest.writeParcelable(mIpConfiguration, flags);
         dest.writeString(dhcpServer);
         dest.writeString(defaultGwMacAddress);
-        dest.writeInt(autoJoinStatus);
         dest.writeInt(selfAdded ? 1 : 0);
         dest.writeInt(didSelfAdd ? 1 : 0);
         dest.writeInt(validatedInternetAccess ? 1 : 0);
@@ -1578,14 +1735,10 @@
         dest.writeInt(lastUpdateUid);
         dest.writeString(creatorName);
         dest.writeString(lastUpdateName);
-        dest.writeLong(blackListTimestamp);
         dest.writeLong(lastConnectionFailure);
         dest.writeLong(lastRoamingFailure);
         dest.writeInt(lastRoamingFailureReason);
         dest.writeLong(roamingFailureBlackListTimeMilli);
-        dest.writeInt(numConnectionFailures);
-        dest.writeInt(numIpConfigFailures);
-        dest.writeInt(numAuthFailures);
         dest.writeInt(numScorerOverride);
         dest.writeInt(numScorerOverrideAndSwitchedNetwork);
         dest.writeInt(numAssociation);
@@ -1596,11 +1749,10 @@
         dest.writeInt(numTicksAtBadRSSI);
         dest.writeInt(numTicksAtNotHighRSSI);
         dest.writeInt(numUserTriggeredJoinAttempts);
-        dest.writeInt(autoJoinUseAggressiveJoinAttemptThreshold);
-        dest.writeInt(autoJoinBailedDueToLowRssi ? 1 : 0);
         dest.writeInt(userApproved);
         dest.writeInt(numNoInternetAccessReports);
         dest.writeInt(noInternetAccessExpected ? 1 : 0);
+        dest.writeInt(shared ? 1 : 0);
     }
 
     /** Implement the Parcelable interface {@hide} */
@@ -1610,12 +1762,11 @@
                 WifiConfiguration config = new WifiConfiguration();
                 config.networkId = in.readInt();
                 config.status = in.readInt();
-                config.disableReason = in.readInt();
+                config.mNetworkSelectionStatus.readFromParcel(in);
                 config.SSID = in.readString();
                 config.BSSID = in.readString();
                 config.apBand = in.readInt();
                 config.apChannel = in.readInt();
-                config.autoJoinBSSID = in.readString();
                 config.FQDN = in.readString();
                 config.providerFriendlyName = in.readString();
                 int numRoamingConsortiumIds = in.readInt();
@@ -1640,11 +1791,9 @@
                 config.allowedGroupCiphers    = readBitSet(in);
 
                 config.enterpriseConfig = in.readParcelable(null);
-
                 config.mIpConfiguration = in.readParcelable(null);
                 config.dhcpServer = in.readString();
                 config.defaultGwMacAddress = in.readString();
-                config.autoJoinStatus = in.readInt();
                 config.selfAdded = in.readInt() != 0;
                 config.didSelfAdd = in.readInt() != 0;
                 config.validatedInternetAccess = in.readInt() != 0;
@@ -1654,14 +1803,10 @@
                 config.lastUpdateUid = in.readInt();
                 config.creatorName = in.readString();
                 config.lastUpdateName = in.readString();
-                config.blackListTimestamp = in.readLong();
                 config.lastConnectionFailure = in.readLong();
                 config.lastRoamingFailure = in.readLong();
                 config.lastRoamingFailureReason = in.readInt();
                 config.roamingFailureBlackListTimeMilli = in.readLong();
-                config.numConnectionFailures = in.readInt();
-                config.numIpConfigFailures = in.readInt();
-                config.numAuthFailures = in.readInt();
                 config.numScorerOverride = in.readInt();
                 config.numScorerOverrideAndSwitchedNetwork = in.readInt();
                 config.numAssociation = in.readInt();
@@ -1672,11 +1817,10 @@
                 config.numTicksAtBadRSSI = in.readInt();
                 config.numTicksAtNotHighRSSI = in.readInt();
                 config.numUserTriggeredJoinAttempts = in.readInt();
-                config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt();
-                config.autoJoinBailedDueToLowRssi = in.readInt() != 0;
                 config.userApproved = in.readInt();
                 config.numNoInternetAccessReports = in.readInt();
                 config.noInternetAccessExpected = in.readInt() != 0;
+                config.shared = in.readInt() != 0;
                 return config;
             }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 7a5a74f..db40cd8 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1007,7 +1007,7 @@
 
     /**
      * @return true if this adapter supports Neighbour Awareness Network APIs
-     * @hide
+     * @hide PROPOSED_NAN_API
      */
     public boolean isNanSupported() {
         return isFeatureSupported(WIFI_FEATURE_NAN);
@@ -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);
diff --git a/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java b/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java
new file mode 100644
index 0000000..17cc29f
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java
@@ -0,0 +1,150 @@
+/*
+ * 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.net.wifi;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+/**
+ * A class representing wifi wake reason accounting.
+ */
+
+/** @hide */
+public class WifiWakeReasonAndCounts implements Parcelable {
+    private static final String TAG = "WifiWakeReasonAndCounts";
+    /**
+     * Wlan can wake host, only when it is cmd/event, local driver-fw
+     * functions(non-data, non cmd/event) and rx data.The first packet
+     * from wlan that woke up a sleep host is what is accounted here.
+     * Total wlan wake to application processor would be:
+     * [cmdEventWake + driverFwLocalWake + totalRxDataWake]
+     * A further classification is provided for identifying the reasons
+     * for wakeup.
+     */
+    public int totalCmdEventWake;
+    public int totalDriverFwLocalWake;
+    public int totalRxDataWake;
+
+    public int rxUnicast;
+    public int rxMulticast;
+    public int rxBroadcast;
+
+    public int icmp;
+    public int icmp6;
+    public int icmp6Ra;
+    public int icmp6Na;
+    public int icmp6Ns;
+
+    public int ipv4RxMulticast;
+    public int ipv6Multicast;
+    public int otherRxMulticast;
+
+    /* {@hide} */
+    public WifiWakeReasonAndCounts () {
+    }
+
+    @Override
+    /* {@hide} */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(" totalCmdEventWake ").append(totalCmdEventWake);
+        sb.append(" totalDriverFwLocalWake ").append(totalDriverFwLocalWake);
+        sb.append(" totalRxDataWake ").append(totalRxDataWake);
+
+        sb.append(" rxUnicast ").append(rxUnicast);
+        sb.append(" rxMulticast ").append(rxMulticast);
+        sb.append(" rxBroadcast ").append(rxBroadcast);
+
+        sb.append(" icmp ").append(icmp);
+        sb.append(" icmp6 ").append(icmp6);
+        sb.append(" icmp6Ra ").append(icmp6Ra);
+        sb.append(" icmp6Na ").append(icmp6Na);
+        sb.append(" icmp6Ns ").append(icmp6Ns);
+
+        sb.append(" ipv4RxMulticast ").append(ipv4RxMulticast);
+        sb.append(" ipv6Multicast ").append(ipv6Multicast);
+        sb.append(" otherRxMulticast ").append(otherRxMulticast);
+        return sb.toString();
+    }
+
+    /* Implement the Parcelable interface
+     * {@hide}
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /* Implement the Parcelable interface
+     * {@hide}
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(totalCmdEventWake);
+        dest.writeInt(totalDriverFwLocalWake);
+        dest.writeInt(totalRxDataWake);
+
+        dest.writeInt(rxUnicast);
+        dest.writeInt(rxMulticast);
+        dest.writeInt(rxBroadcast);
+
+        dest.writeInt(icmp);
+        dest.writeInt(icmp6);
+        dest.writeInt(icmp6Ra);
+        dest.writeInt(icmp6Na);
+        dest.writeInt(icmp6Ns);
+
+        dest.writeInt(ipv4RxMulticast);
+        dest.writeInt(ipv6Multicast);
+        dest.writeInt(otherRxMulticast);
+    }
+
+    /* Implement the Parcelable interface
+     * {@hide}
+     */
+    public static final Creator<WifiWakeReasonAndCounts> CREATOR =
+        new Creator<WifiWakeReasonAndCounts>() {
+            public WifiWakeReasonAndCounts createFromParcel(Parcel in) {
+                WifiWakeReasonAndCounts counts = new WifiWakeReasonAndCounts();
+                counts.totalCmdEventWake = in.readInt();
+                counts.totalDriverFwLocalWake = in.readInt();
+                counts.totalRxDataWake = in.readInt();
+
+                counts.rxUnicast = in.readInt();
+                counts.rxMulticast = in.readInt();
+                counts.rxBroadcast = in.readInt();
+
+                counts.icmp = in.readInt();
+                counts.icmp6 = in.readInt();
+                counts.icmp6Ra = in.readInt();
+                counts.icmp6Na = in.readInt();
+                counts.icmp6Ns = in.readInt();
+
+                counts.ipv4RxMulticast = in.readInt();
+                counts.ipv6Multicast = in.readInt();
+                counts.otherRxMulticast = in.readInt();
+                return counts;
+            }
+            /* Implement the Parcelable interface
+             * {@hide}
+             */
+            @Override
+            public WifiWakeReasonAndCounts[] newArray(int size) {
+                return new WifiWakeReasonAndCounts[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/nan/ConfigRequest.aidl b/wifi/java/android/net/wifi/nan/ConfigRequest.aidl
new file mode 100644
index 0000000..38dddc2
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/ConfigRequest.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.net.wifi.nan;
+
+parcelable ConfigRequest;
diff --git a/wifi/java/android/net/wifi/nan/ConfigRequest.java b/wifi/java/android/net/wifi/nan/ConfigRequest.java
new file mode 100644
index 0000000..23e3754
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/ConfigRequest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Defines a request object to configure a Wi-Fi NAN network. Built using
+ * {@link ConfigRequest.Builder}. Configuration is requested using
+ * {@link WifiNanManager#requestConfig(ConfigRequest)}. Note that the actual
+ * achieved configuration may be different from the requested configuration -
+ * since multiple applications may request different configurations.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class ConfigRequest implements Parcelable {
+    /**
+     * Lower range of possible cluster ID.
+     *
+     * @hide
+     */
+    public static final int CLUSTER_ID_MIN = 0;
+
+    /**
+     * Upper range of possible cluster ID.
+     *
+     * @hide
+     */
+    public static final int CLUSTER_ID_MAX = 0xFFFF;
+
+    /**
+     * Indicates whether 5G band support is requested.
+     *
+     * @hide
+     */
+    public final boolean mSupport5gBand;
+
+    /**
+     * Specifies the desired master preference.
+     *
+     * @hide
+     */
+    public final int mMasterPreference;
+
+    /**
+     * Specifies the desired lower range of the cluster ID. Must be lower then
+     * {@link ConfigRequest#mClusterHigh}.
+     *
+     * @hide
+     */
+    public final int mClusterLow;
+
+    /**
+     * Specifies the desired higher range of the cluster ID. Must be higher then
+     * {@link ConfigRequest#mClusterLow}.
+     *
+     * @hide
+     */
+    public final int mClusterHigh;
+
+    private ConfigRequest(boolean support5gBand, int masterPreference, int clusterLow,
+            int clusterHigh) {
+        mSupport5gBand = support5gBand;
+        mMasterPreference = masterPreference;
+        mClusterLow = clusterLow;
+        mClusterHigh = clusterHigh;
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigRequest [mSupport5gBand=" + mSupport5gBand + ", mMasterPreference="
+                + mMasterPreference + ", mClusterLow=" + mClusterLow + ", mClusterHigh="
+                + mClusterHigh + "]";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mSupport5gBand ? 1 : 0);
+        dest.writeInt(mMasterPreference);
+        dest.writeInt(mClusterLow);
+        dest.writeInt(mClusterHigh);
+    }
+
+    public static final Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
+        @Override
+        public ConfigRequest[] newArray(int size) {
+            return new ConfigRequest[size];
+        }
+
+        @Override
+        public ConfigRequest createFromParcel(Parcel in) {
+            boolean support5gBand = in.readInt() != 0;
+            int masterPreference = in.readInt();
+            int clusterLow = in.readInt();
+            int clusterHigh = in.readInt();
+            return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh);
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof ConfigRequest)) {
+            return false;
+        }
+
+        ConfigRequest lhs = (ConfigRequest) o;
+
+        return mSupport5gBand == lhs.mSupport5gBand && mMasterPreference == lhs.mMasterPreference
+                && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+
+        result = 31 * result + (mSupport5gBand ? 1 : 0);
+        result = 31 * result + mMasterPreference;
+        result = 31 * result + mClusterLow;
+        result = 31 * result + mClusterHigh;
+
+        return result;
+    }
+
+    /**
+     * Builder used to build {@link ConfigRequest} objects.
+     */
+    public static final class Builder {
+        private boolean mSupport5gBand;
+        private int mMasterPreference;
+        private int mClusterLow;
+        private int mClusterHigh;
+
+        /**
+         * Default constructor for the Builder.
+         */
+        public Builder() {
+            mSupport5gBand = false;
+            mMasterPreference = 0;
+            mClusterLow = 0;
+            mClusterHigh = CLUSTER_ID_MAX;
+        }
+
+        /**
+         * Specify whether 5G band support is required in this request.
+         *
+         * @param support5gBand Support for 5G band is required.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setSupport5gBand(boolean support5gBand) {
+            mSupport5gBand = support5gBand;
+            return this;
+        }
+
+        /**
+         * Specify the Master Preference requested. The permitted range is 0 to
+         * 255 with 1 and 255 excluded (reserved).
+         *
+         * @param masterPreference The requested master preference
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setMasterPreference(int masterPreference) {
+            if (masterPreference < 0) {
+                throw new IllegalArgumentException(
+                        "Master Preference specification must be non-negative");
+            }
+            if (masterPreference == 1 || masterPreference == 255 || masterPreference > 255) {
+                throw new IllegalArgumentException("Master Preference specification must not "
+                        + "exceed 255 or use 1 or 255 (reserved values)");
+            }
+
+            mMasterPreference = masterPreference;
+            return this;
+        }
+
+        /**
+         * The Cluster ID is generated randomly for new NAN networks. Specify
+         * the lower range of the cluster ID. The upper range is specified using
+         * the {@link ConfigRequest.Builder#setClusterHigh(int)}. The permitted
+         * range is 0 to the value specified by
+         * {@link ConfigRequest.Builder#setClusterHigh(int)}. Equality is
+         * permitted which restricts the Cluster ID to the specified value.
+         *
+         * @param clusterLow The lower range of the generated cluster ID.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setClusterLow(..).setClusterHigh(..)}.
+         */
+        public Builder setClusterLow(int clusterLow) {
+            if (clusterLow < CLUSTER_ID_MIN) {
+                throw new IllegalArgumentException("Cluster specification must be non-negative");
+            }
+            if (clusterLow > CLUSTER_ID_MAX) {
+                throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
+            }
+
+            mClusterLow = clusterLow;
+            return this;
+        }
+
+        /**
+         * The Cluster ID is generated randomly for new NAN networks. Specify
+         * the lower upper of the cluster ID. The lower range is specified using
+         * the {@link ConfigRequest.Builder#setClusterLow(int)}. The permitted
+         * range is the value specified by
+         * {@link ConfigRequest.Builder#setClusterLow(int)} to 0xFFFF. Equality
+         * is permitted which restricts the Cluster ID to the specified value.
+         *
+         * @param clusterHigh The upper range of the generated cluster ID.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setClusterLow(..).setClusterHigh(..)}.
+         */
+        public Builder setClusterHigh(int clusterHigh) {
+            if (clusterHigh < CLUSTER_ID_MIN) {
+                throw new IllegalArgumentException("Cluster specification must be non-negative");
+            }
+            if (clusterHigh > CLUSTER_ID_MAX) {
+                throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
+            }
+
+            mClusterHigh = clusterHigh;
+            return this;
+        }
+
+        /**
+         * Build {@link ConfigRequest} given the current requests made on the
+         * builder.
+         */
+        public ConfigRequest build() {
+            if (mClusterLow > mClusterHigh) {
+                throw new IllegalArgumentException(
+                        "Invalid argument combination - must have Cluster Low <= Cluster High");
+            }
+
+            return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh);
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl b/wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl
new file mode 100644
index 0000000..13efc36
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.net.wifi.nan.ConfigRequest;
+
+/**
+ * Callback interface that WifiNanManager implements
+ *
+ * {@hide}
+ */
+oneway interface IWifiNanEventListener
+{
+    void onConfigCompleted(in ConfigRequest completedConfig);
+    void onConfigFailed(int reason);
+    void onNanDown(int reason);
+    void onIdentityChanged();
+}
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
new file mode 100644
index 0000000..ff3d29f
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.app.PendingIntent;
+
+import android.net.wifi.nan.ConfigRequest;
+import android.net.wifi.nan.IWifiNanEventListener;
+import android.net.wifi.nan.IWifiNanSessionListener;
+import android.net.wifi.nan.PublishData;
+import android.net.wifi.nan.PublishSettings;
+import android.net.wifi.nan.SubscribeData;
+import android.net.wifi.nan.SubscribeSettings;
+
+/**
+ * Interface that WifiNanService implements
+ *
+ * {@hide}
+ */
+interface IWifiNanManager
+{
+    // client API
+    void connect(in IBinder binder, in IWifiNanEventListener listener, int events);
+    void disconnect(in IBinder binder);
+    void requestConfig(in ConfigRequest configRequest);
+
+    // session API
+    int createSession(in IWifiNanSessionListener listener, int events);
+    void publish(int sessionId, in PublishData publishData, in PublishSettings publishSettings);
+    void subscribe(int sessionId, in SubscribeData subscribeData,
+            in SubscribeSettings subscribeSettings);
+    void sendMessage(int sessionId, int peerId, in byte[] message, int messageLength);
+    void stopSession(int sessionId);
+    void destroySession(int sessionId);
+}
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl b/wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl
new file mode 100644
index 0000000..773f83b
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+/**
+ * Callback interface that WifiNanManager implements
+ *
+ * {@hide}
+ */
+oneway interface IWifiNanSessionListener
+{
+    void onPublishFail(int reason);
+    void onPublishTerminated(int reason);
+
+    void onSubscribeFail(int reason);
+    void onSubscribeTerminated(int reason);
+
+    void onMatch(int peerId, in byte[] serviceSpecificInfo,
+            int serviceSpecificInfoLength, in byte[] matchFilter, int matchFilterLength);
+
+    void onMessageSendSuccess();
+    void onMessageSendFail(int reason);
+    void onMessageReceived(int peerId, in byte[] message, int messageLength);
+}
diff --git a/wifi/java/android/net/wifi/nan/PublishData.aidl b/wifi/java/android/net/wifi/nan/PublishData.aidl
new file mode 100644
index 0000000..15e4ddf
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/PublishData.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.net.wifi.nan;
+
+parcelable PublishData;
diff --git a/wifi/java/android/net/wifi/nan/PublishData.java b/wifi/java/android/net/wifi/nan/PublishData.java
new file mode 100644
index 0000000..80119eb
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/PublishData.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * Defines the data for a NAN publish session. Built using
+ * {@link PublishData.Builder}. Publish is done using
+ * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
+ * or {@link WifiNanPublishSession#publish(PublishData, PublishSettings)}.
+ * @hide PROPOSED_NAN_API
+ */
+public class PublishData implements Parcelable {
+    /**
+     * @hide
+     */
+    public final String mServiceName;
+
+    /**
+     * @hide
+     */
+    public final int mServiceSpecificInfoLength;
+
+    /**
+     * @hide
+     */
+    public final byte[] mServiceSpecificInfo;
+
+    /**
+     * @hide
+     */
+    public final int mTxFilterLength;
+
+    /**
+     * @hide
+     */
+    public final byte[] mTxFilter;
+
+    /**
+     * @hide
+     */
+    public final int mRxFilterLength;
+
+    /**
+     * @hide
+     */
+    public final byte[] mRxFilter;
+
+    private PublishData(String serviceName, byte[] serviceSpecificInfo,
+            int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
+            int rxFilterLength) {
+        mServiceName = serviceName;
+        mServiceSpecificInfoLength = serviceSpecificInfoLength;
+        mServiceSpecificInfo = serviceSpecificInfo;
+        mTxFilterLength = txFilterLength;
+        mTxFilter = txFilter;
+        mRxFilterLength = rxFilterLength;
+        mRxFilter = rxFilter;
+    }
+
+    @Override
+    public String toString() {
+        return "PublishData [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
+                + (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
+                + "', mTxFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
+                + ", mRxFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
+                + "']";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mServiceName);
+        dest.writeInt(mServiceSpecificInfoLength);
+        if (mServiceSpecificInfoLength != 0) {
+            dest.writeByteArray(mServiceSpecificInfo, 0, mServiceSpecificInfoLength);
+        }
+        dest.writeInt(mTxFilterLength);
+        if (mTxFilterLength != 0) {
+            dest.writeByteArray(mTxFilter, 0, mTxFilterLength);
+        }
+        dest.writeInt(mRxFilterLength);
+        if (mRxFilterLength != 0) {
+            dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
+        }
+    }
+
+    public static final Creator<PublishData> CREATOR = new Creator<PublishData>() {
+        @Override
+        public PublishData[] newArray(int size) {
+            return new PublishData[size];
+        }
+
+        @Override
+        public PublishData createFromParcel(Parcel in) {
+            String serviceName = in.readString();
+            int ssiLength = in.readInt();
+            byte[] ssi = new byte[ssiLength];
+            if (ssiLength != 0) {
+                in.readByteArray(ssi);
+            }
+            int txFilterLength = in.readInt();
+            byte[] txFilter = new byte[txFilterLength];
+            if (txFilterLength != 0) {
+                in.readByteArray(txFilter);
+            }
+            int rxFilterLength = in.readInt();
+            byte[] rxFilter = new byte[rxFilterLength];
+            if (rxFilterLength != 0) {
+                in.readByteArray(rxFilter);
+            }
+
+            return new PublishData(serviceName, ssi, ssiLength, txFilter, txFilterLength, rxFilter,
+                    rxFilterLength);
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof PublishData)) {
+            return false;
+        }
+
+        PublishData lhs = (PublishData) o;
+
+        if (!mServiceName.equals(lhs.mServiceName)
+                || mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
+                || mTxFilterLength != lhs.mTxFilterLength
+                || mRxFilterLength != lhs.mRxFilterLength) {
+            return false;
+        }
+
+        if (mServiceSpecificInfo != null && lhs.mServiceSpecificInfo != null) {
+            for (int i = 0; i < mServiceSpecificInfoLength; ++i) {
+                if (mServiceSpecificInfo[i] != lhs.mServiceSpecificInfo[i]) {
+                    return false;
+                }
+            }
+        } else if (mServiceSpecificInfoLength != 0) {
+            return false; // invalid != invalid
+        }
+
+        if (mTxFilter != null && lhs.mTxFilter != null) {
+            for (int i = 0; i < mTxFilterLength; ++i) {
+                if (mTxFilter[i] != lhs.mTxFilter[i]) {
+                    return false;
+                }
+            }
+        } else if (mTxFilterLength != 0) {
+            return false; // invalid != invalid
+        }
+
+        if (mRxFilter != null && lhs.mRxFilter != null) {
+            for (int i = 0; i < mRxFilterLength; ++i) {
+                if (mRxFilter[i] != lhs.mRxFilter[i]) {
+                    return false;
+                }
+            }
+        } else if (mRxFilterLength != 0) {
+            return false; // invalid != invalid
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+
+        result = 31 * result + mServiceName.hashCode();
+        result = 31 * result + mServiceSpecificInfoLength;
+        result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
+        result = 31 * result + mTxFilterLength;
+        result = 31 * result + Arrays.hashCode(mTxFilter);
+        result = 31 * result + mRxFilterLength;
+        result = 31 * result + Arrays.hashCode(mRxFilter);
+
+        return result;
+    }
+
+    /**
+     * Builder used to build {@link PublishData} objects.
+     */
+    public static final class Builder {
+        private String mServiceName;
+        private int mServiceSpecificInfoLength;
+        private byte[] mServiceSpecificInfo = new byte[0];
+        private int mTxFilterLength;
+        private byte[] mTxFilter = new byte[0];
+        private int mRxFilterLength;
+        private byte[] mRxFilter = new byte[0];
+
+        /**
+         * Specify the service name of the publish session. The actual on-air
+         * value is a 6 byte hashed representation of this string.
+         *
+         * @param serviceName The service name for the publish session.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setServiceName(String serviceName) {
+            mServiceName = serviceName;
+            return this;
+        }
+
+        /**
+         * Specify service specific information for the publish session. This is
+         * a free-form byte array available to the application to send
+         * additional information as part of the discovery operation - i.e. it
+         * will not be used to determine whether a publish/subscribe match
+         * occurs.
+         *
+         * @param serviceSpecificInfo A byte-array for the service-specific
+         *            information field.
+         * @param serviceSpecificInfoLength The length of the byte-array to be
+         *            used.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setServiceSpecificInfo(byte[] serviceSpecificInfo,
+                int serviceSpecificInfoLength) {
+            if (serviceSpecificInfoLength != 0 && (serviceSpecificInfo == null
+                    || serviceSpecificInfo.length < serviceSpecificInfoLength)) {
+                throw new IllegalArgumentException("Non-matching combination of "
+                        + "serviceSpecificInfo and serviceSpecificInfoLength");
+            }
+            mServiceSpecificInfoLength = serviceSpecificInfoLength;
+            mServiceSpecificInfo = serviceSpecificInfo;
+            return this;
+        }
+
+        /**
+         * Specify service specific information for the publish session - same
+         * as {@link PublishData.Builder#setServiceSpecificInfo(byte[], int)}
+         * but obtaining the data from a String.
+         *
+         * @param serviceSpecificInfoStr The service specific information string
+         *            to be included (as a byte array) in the publish
+         *            information.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setServiceSpecificInfo(String serviceSpecificInfoStr) {
+            mServiceSpecificInfoLength = serviceSpecificInfoStr.length();
+            mServiceSpecificInfo = serviceSpecificInfoStr.getBytes();
+            return this;
+        }
+
+        /**
+         * The transmit filter for an active publish session
+         * {@link PublishSettings.Builder#setPublishType(int)} and
+         * {@link PublishSettings#PUBLISH_TYPE_UNSOLICITED}. Included in
+         * transmitted publish packets and used by receivers (subscribers) to
+         * determine whether they match - in addition to just relying on the
+         * service name.
+         * <p>
+         * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+         * is available to form and parse.
+         *
+         * @param txFilter The byte-array containing the LV formatted transmit
+         *            filter.
+         * @param txFilterLength The number of bytes in the transmit filter
+         *            argument.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setTxFilter(byte[] txFilter, int txFilterLength) {
+            if (txFilterLength != 0 && (txFilter == null || txFilter.length < txFilterLength)) {
+                throw new IllegalArgumentException(
+                        "Non-matching combination of txFilter and txFilterLength");
+            }
+            mTxFilter = txFilter;
+            mTxFilterLength = txFilterLength;
+            return this;
+        }
+
+        /**
+         * The transmit filter for a passive publish session
+         * {@link PublishSettings.Builder#setPublishType(int)} and
+         * {@link PublishSettings#PUBLISH_TYPE_SOLICITED}. Used by the publisher
+         * to determine whether they match transmitted subscriber packets
+         * (active subscribers) - in addition to just relying on the service
+         * name.
+         * <p>
+         * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+         * is available to form and parse.
+         *
+         * @param rxFilter The byte-array containing the LV formatted receive
+         *            filter.
+         * @param rxFilterLength The number of bytes in the receive filter
+         *            argument.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setRxFilter(byte[] rxFilter, int rxFilterLength) {
+            if (rxFilterLength != 0 && (rxFilter == null || rxFilter.length < rxFilterLength)) {
+                throw new IllegalArgumentException(
+                        "Non-matching combination of rxFilter and rxFilterLength");
+            }
+            mRxFilter = rxFilter;
+            mRxFilterLength = rxFilterLength;
+            return this;
+        }
+
+        /**
+         * Build {@link PublishData} given the current requests made on the
+         * builder.
+         */
+        public PublishData build() {
+            return new PublishData(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
+                    mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength);
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/PublishSettings.aidl b/wifi/java/android/net/wifi/nan/PublishSettings.aidl
new file mode 100644
index 0000000..ff69293
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/PublishSettings.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.net.wifi.nan;
+
+parcelable PublishSettings;
diff --git a/wifi/java/android/net/wifi/nan/PublishSettings.java b/wifi/java/android/net/wifi/nan/PublishSettings.java
new file mode 100644
index 0000000..bbc5340
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/PublishSettings.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Defines the settings (configuration) for a NAN publish session. Built using
+ * {@link PublishSettings.Builder}. Publish is done using
+ * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
+ * or {@link WifiNanPublishSession#publish(PublishData, PublishSettings)}.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class PublishSettings implements Parcelable {
+
+    /**
+     * Defines an unsolicited publish session - i.e. a publish session where
+     * publish packets are transmitted over-the-air. Configuration is done using
+     * {@link PublishSettings.Builder#setPublishType(int)}.
+     */
+    public static final int PUBLISH_TYPE_UNSOLICITED = 0;
+
+    /**
+     * Defines a solicited publish session - i.e. a publish session where
+     * publish packets are not transmitted over-the-air and the device listens
+     * and matches to transmitted subscribe packets. Configuration is done using
+     * {@link PublishSettings.Builder#setPublishType(int)}.
+     */
+    public static final int PUBLISH_TYPE_SOLICITED = 1;
+
+    /**
+     * @hide
+     */
+    public final int mPublishType;
+
+    /**
+     * @hide
+     */
+    public final int mPublishCount;
+
+    /**
+     * @hide
+     */
+    public final int mTtlSec;
+
+    private PublishSettings(int publishType, int publichCount, int ttlSec) {
+        mPublishType = publishType;
+        mPublishCount = publichCount;
+        mTtlSec = ttlSec;
+    }
+
+    @Override
+    public String toString() {
+        return "PublishSettings [mPublishType=" + mPublishType + ", mPublishCount=" + mPublishCount
+                + ", mTtlSec=" + mTtlSec + "]";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mPublishType);
+        dest.writeInt(mPublishCount);
+        dest.writeInt(mTtlSec);
+    }
+
+    public static final Creator<PublishSettings> CREATOR = new Creator<PublishSettings>() {
+        @Override
+        public PublishSettings[] newArray(int size) {
+            return new PublishSettings[size];
+        }
+
+        @Override
+        public PublishSettings createFromParcel(Parcel in) {
+            int publishType = in.readInt();
+            int publishCount = in.readInt();
+            int ttlSec = in.readInt();
+            return new PublishSettings(publishType, publishCount, ttlSec);
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof PublishSettings)) {
+            return false;
+        }
+
+        PublishSettings lhs = (PublishSettings) o;
+
+        return mPublishType == lhs.mPublishType && mPublishCount == lhs.mPublishCount
+                && mTtlSec == lhs.mTtlSec;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+
+        result = 31 * result + mPublishType;
+        result = 31 * result + mPublishCount;
+        result = 31 * result + mTtlSec;
+
+        return result;
+    }
+
+    /**
+     * Builder used to build {@link PublishSettings} objects.
+     */
+    public static final class Builder {
+        int mPublishType;
+        int mPublishCount;
+        int mTtlSec;
+
+        /**
+         * Sets the type of the publish session: solicited (aka active - publish
+         * packets are transmitted over-the-air), or unsolicited (aka passive -
+         * no publish packets are transmitted, a match is made against an active
+         * subscribe session whose packets are transmitted over-the-air).
+         *
+         * @param publishType Publish session type: solicited (
+         *            {@link PublishSettings#PUBLISH_TYPE_SOLICITED}) or
+         *            unsolicited (
+         *            {@link PublishSettings#PUBLISH_TYPE_UNSOLICITED}).
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setPublishType(int publishType) {
+            if (publishType < PUBLISH_TYPE_UNSOLICITED || publishType > PUBLISH_TYPE_SOLICITED) {
+                throw new IllegalArgumentException("Invalid publishType - " + publishType);
+            }
+            mPublishType = publishType;
+            return this;
+        }
+
+        /**
+         * Sets the number of times a solicited (
+         * {@link PublishSettings.Builder#setPublishType(int)}) publish session
+         * will transmit a packet. When the count is reached an event will be
+         * generated for {@link WifiNanSessionListener#onPublishTerminated(int)}
+         * with reason={@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param publishCount Number of publish packets to transmit.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setPublishCount(int publishCount) {
+            if (publishCount < 0) {
+                throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
+            }
+            mPublishCount = publishCount;
+            return this;
+        }
+
+        /**
+         * Sets the time interval (in seconds) a solicited (
+         * {@link PublishSettings.Builder#setPublishCount(int)}) publish session
+         * will be alive - i.e. transmitting a packet. When the TTL is reached
+         * an event will be generated for
+         * {@link WifiNanSessionListener#onPublishTerminated(int)} with reason=
+         * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param ttlSec Lifetime of a publish session in seconds.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setTtlSec(int ttlSec) {
+            if (ttlSec < 0) {
+                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+            }
+            mTtlSec = ttlSec;
+            return this;
+        }
+
+        /**
+         * Build {@link PublishSettings} given the current requests made on the
+         * builder.
+         */
+        public PublishSettings build() {
+            return new PublishSettings(mPublishType, mPublishCount, mTtlSec);
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/SubscribeData.aidl b/wifi/java/android/net/wifi/nan/SubscribeData.aidl
new file mode 100644
index 0000000..662fdb8
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/SubscribeData.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.net.wifi.nan;
+
+parcelable SubscribeData;
diff --git a/wifi/java/android/net/wifi/nan/SubscribeData.java b/wifi/java/android/net/wifi/nan/SubscribeData.java
new file mode 100644
index 0000000..cd6e918
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/SubscribeData.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * Defines the data for a NAN subscribe session. Built using
+ * {@link SubscribeData.Builder}. Subscribe is done using
+ * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
+ * or
+ * {@link WifiNanSubscribeSession#subscribe(SubscribeData, SubscribeSettings)}.
+ * @hide PROPOSED_NAN_API
+ */
+public class SubscribeData implements Parcelable {
+    /**
+     * @hide
+     */
+    public final String mServiceName;
+
+    /**
+     * @hide
+     */
+    public final int mServiceSpecificInfoLength;
+
+    /**
+     * @hide
+     */
+    public final byte[] mServiceSpecificInfo;
+
+    /**
+     * @hide
+     */
+    public final int mTxFilterLength;
+
+    /**
+     * @hide
+     */
+    public final byte[] mTxFilter;
+
+    /**
+     * @hide
+     */
+    public final int mRxFilterLength;
+
+    /**
+     * @hide
+     */
+    public final byte[] mRxFilter;
+
+    private SubscribeData(String serviceName, byte[] serviceSpecificInfo,
+            int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
+            int rxFilterLength) {
+        mServiceName = serviceName;
+        mServiceSpecificInfoLength = serviceSpecificInfoLength;
+        mServiceSpecificInfo = serviceSpecificInfo;
+        mTxFilterLength = txFilterLength;
+        mTxFilter = txFilter;
+        mRxFilterLength = rxFilterLength;
+        mRxFilter = rxFilter;
+    }
+
+    @Override
+    public String toString() {
+        return "SubscribeData [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
+                + (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
+                + "', mTxFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
+                + ", mRxFilter="
+                + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
+                + "']";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mServiceName);
+        dest.writeInt(mServiceSpecificInfoLength);
+        if (mServiceSpecificInfoLength != 0) {
+            dest.writeByteArray(mServiceSpecificInfo, 0, mServiceSpecificInfoLength);
+        }
+        dest.writeInt(mTxFilterLength);
+        if (mTxFilterLength != 0) {
+            dest.writeByteArray(mTxFilter, 0, mTxFilterLength);
+        }
+        dest.writeInt(mRxFilterLength);
+        if (mRxFilterLength != 0) {
+            dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
+        }
+    }
+
+    public static final Creator<SubscribeData> CREATOR = new Creator<SubscribeData>() {
+        @Override
+        public SubscribeData[] newArray(int size) {
+            return new SubscribeData[size];
+        }
+
+        @Override
+        public SubscribeData createFromParcel(Parcel in) {
+            String serviceName = in.readString();
+            int ssiLength = in.readInt();
+            byte[] ssi = new byte[ssiLength];
+            if (ssiLength != 0) {
+                in.readByteArray(ssi);
+            }
+            int txFilterLength = in.readInt();
+            byte[] txFilter = new byte[txFilterLength];
+            if (txFilterLength != 0) {
+                in.readByteArray(txFilter);
+            }
+            int rxFilterLength = in.readInt();
+            byte[] rxFilter = new byte[rxFilterLength];
+            if (rxFilterLength != 0) {
+                in.readByteArray(rxFilter);
+            }
+
+            return new SubscribeData(serviceName, ssi, ssiLength, txFilter, txFilterLength,
+                    rxFilter, rxFilterLength);
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof SubscribeData)) {
+            return false;
+        }
+
+        SubscribeData lhs = (SubscribeData) o;
+
+        if (!mServiceName.equals(lhs.mServiceName)
+                || mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
+                || mTxFilterLength != lhs.mTxFilterLength
+                || mRxFilterLength != lhs.mRxFilterLength) {
+            return false;
+        }
+
+        if (mServiceSpecificInfo != null && lhs.mServiceSpecificInfo != null) {
+            for (int i = 0; i < mServiceSpecificInfoLength; ++i) {
+                if (mServiceSpecificInfo[i] != lhs.mServiceSpecificInfo[i]) {
+                    return false;
+                }
+            }
+        } else if (mServiceSpecificInfoLength != 0) {
+            return false; // invalid != invalid
+        }
+
+        if (mTxFilter != null && lhs.mTxFilter != null) {
+            for (int i = 0; i < mTxFilterLength; ++i) {
+                if (mTxFilter[i] != lhs.mTxFilter[i]) {
+                    return false;
+                }
+            }
+        } else if (mTxFilterLength != 0) {
+            return false; // invalid != invalid
+        }
+
+        if (mRxFilter != null && lhs.mRxFilter != null) {
+            for (int i = 0; i < mRxFilterLength; ++i) {
+                if (mRxFilter[i] != lhs.mRxFilter[i]) {
+                    return false;
+                }
+            }
+        } else if (mRxFilterLength != 0) {
+            return false; // invalid != invalid
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+
+        result = 31 * result + mServiceName.hashCode();
+        result = 31 * result + mServiceSpecificInfoLength;
+        result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
+        result = 31 * result + mTxFilterLength;
+        result = 31 * result + Arrays.hashCode(mTxFilter);
+        result = 31 * result + mRxFilterLength;
+        result = 31 * result + Arrays.hashCode(mRxFilter);
+
+        return result;
+    }
+
+    /**
+     * Builder used to build {@link SubscribeData} objects.
+     */
+    public static final class Builder {
+        private String mServiceName;
+        private int mServiceSpecificInfoLength;
+        private byte[] mServiceSpecificInfo = new byte[0];
+        private int mTxFilterLength;
+        private byte[] mTxFilter = new byte[0];
+        private int mRxFilterLength;
+        private byte[] mRxFilter = new byte[0];
+
+        /**
+         * Specify the service name of the subscribe session. The actual on-air
+         * value is a 6 byte hashed representation of this string.
+         *
+         * @param serviceName The service name for the subscribe session.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setServiceName(String serviceName) {
+            mServiceName = serviceName;
+            return this;
+        }
+
+        /**
+         * Specify service specific information for the subscribe session. This
+         * is a free-form byte array available to the application to send
+         * additional information as part of the discovery operation - i.e. it
+         * will not be used to determine whether a publish/subscribe match
+         * occurs.
+         *
+         * @param serviceSpecificInfo A byte-array for the service-specific
+         *            information field.
+         * @param serviceSpecificInfoLength The length of the byte-array to be
+         *            used.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setServiceSpecificInfo(byte[] serviceSpecificInfo,
+                int serviceSpecificInfoLength) {
+            mServiceSpecificInfoLength = serviceSpecificInfoLength;
+            mServiceSpecificInfo = serviceSpecificInfo;
+            return this;
+        }
+
+        /**
+         * Specify service specific information for the subscribe session - same
+         * as {@link SubscribeData.Builder#setServiceSpecificInfo(byte[], int)}
+         * but obtaining the data from a String.
+         *
+         * @param serviceSpecificInfoStr The service specific information string
+         *            to be included (as a byte array) in the subscribe
+         *            information.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setServiceSpecificInfo(String serviceSpecificInfoStr) {
+            mServiceSpecificInfoLength = serviceSpecificInfoStr.length();
+            mServiceSpecificInfo = serviceSpecificInfoStr.getBytes();
+            return this;
+        }
+
+        /**
+         * The transmit filter for an active subscribe session
+         * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
+         * {@link SubscribeSettings#SUBSCRIBE_TYPE_ACTIVE}. Included in
+         * transmitted subscribe packets and used by receivers (passive
+         * publishers) to determine whether they match - in addition to just
+         * relying on the service name.
+         * <p>
+         * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+         * is available to form and parse.
+         *
+         * @param txFilter The byte-array containing the LV formatted transmit
+         *            filter.
+         * @param txFilterLength The number of bytes in the transmit filter
+         *            argument.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setTxFilter(byte[] txFilter, int txFilterLength) {
+            mTxFilter = txFilter;
+            mTxFilterLength = txFilterLength;
+            return this;
+        }
+
+        /**
+         * The transmit filter for a passive subsribe session
+         * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
+         * {@link SubscribeSettings#SUBSCRIBE_TYPE_PASSIVE}. Used by the
+         * subscriber to determine whether they match transmitted publish
+         * packets - in addition to just relying on the service name.
+         * <p>
+         * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+         * is available to form and parse.
+         *
+         * @param rxFilter The byte-array containing the LV formatted receive
+         *            filter.
+         * @param rxFilterLength The number of bytes in the receive filter
+         *            argument.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setRxFilter(byte[] rxFilter, int rxFilterLength) {
+            mRxFilter = rxFilter;
+            mRxFilterLength = rxFilterLength;
+            return this;
+        }
+
+        /**
+         * Build {@link SubscribeData} given the current requests made on the
+         * builder.
+         */
+        public SubscribeData build() {
+            return new SubscribeData(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
+                    mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength);
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl b/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl
new file mode 100644
index 0000000..44849bc
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/SubscribeSettings.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.net.wifi.nan;
+
+parcelable SubscribeSettings;
diff --git a/wifi/java/android/net/wifi/nan/SubscribeSettings.java b/wifi/java/android/net/wifi/nan/SubscribeSettings.java
new file mode 100644
index 0000000..5c4f8fb
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/SubscribeSettings.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Defines the settings (configuration) for a NAN subscribe session. Built using
+ * {@link SubscribeSettings.Builder}. Subscribe is done using
+ * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
+ * or {@link WifiNanSubscribeSession#subscribe(SubscribeData, SubscribeSettings)}.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class SubscribeSettings implements Parcelable {
+
+    /**
+     * Defines a passive subscribe session - i.e. a subscribe session where
+     * subscribe packets are not transmitted over-the-air and the device listens
+     * and matches to transmitted publish packets. Configuration is done using
+     * {@link SubscribeSettings.Builder#setSubscribeType(int)}.
+     */
+    public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
+
+    /**
+     * Defines an active subscribe session - i.e. a subscribe session where
+     * subscribe packets are transmitted over-the-air. Configuration is done
+     * using {@link SubscribeSettings.Builder#setSubscribeType(int)}.
+     */
+    public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
+
+    /**
+     * @hide
+     */
+    public final int mSubscribeType;
+
+    /**
+     * @hide
+     */
+    public final int mSubscribeCount;
+
+    /**
+     * @hide
+     */
+    public final int mTtlSec;
+
+    private SubscribeSettings(int subscribeType, int publichCount, int ttlSec) {
+        mSubscribeType = subscribeType;
+        mSubscribeCount = publichCount;
+        mTtlSec = ttlSec;
+    }
+
+    @Override
+    public String toString() {
+        return "SubscribeSettings [mSubscribeType=" + mSubscribeType + ", mSubscribeCount="
+                + mSubscribeCount + ", mTtlSec=" + mTtlSec + "]";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mSubscribeType);
+        dest.writeInt(mSubscribeCount);
+        dest.writeInt(mTtlSec);
+    }
+
+    public static final Creator<SubscribeSettings> CREATOR = new Creator<SubscribeSettings>() {
+        @Override
+        public SubscribeSettings[] newArray(int size) {
+            return new SubscribeSettings[size];
+        }
+
+        @Override
+        public SubscribeSettings createFromParcel(Parcel in) {
+            int subscribeType = in.readInt();
+            int subscribeCount = in.readInt();
+            int ttlSec = in.readInt();
+            return new SubscribeSettings(subscribeType, subscribeCount, ttlSec);
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof SubscribeSettings)) {
+            return false;
+        }
+
+        SubscribeSettings lhs = (SubscribeSettings) o;
+
+        return mSubscribeType == lhs.mSubscribeType && mSubscribeCount == lhs.mSubscribeCount
+                && mTtlSec == lhs.mTtlSec;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+
+        result = 31 * result + mSubscribeType;
+        result = 31 * result + mSubscribeCount;
+        result = 31 * result + mTtlSec;
+
+        return result;
+    }
+
+    /**
+     * Builder used to build {@link SubscribeSettings} objects.
+     */
+    public static final class Builder {
+        int mSubscribeType;
+        int mSubscribeCount;
+        int mTtlSec;
+
+        /**
+         * Sets the type of the subscribe session: active (subscribe packets are
+         * transmitted over-the-air), or passive (no subscribe packets are
+         * transmitted, a match is made against a solicited/active publish
+         * session whose packets are transmitted over-the-air).
+         *
+         * @param subscribeType Subscribe session type: active (
+         *            {@link SubscribeSettings#SUBSCRIBE_TYPE_ACTIVE}) or
+         *            passive ( {@link SubscribeSettings#SUBSCRIBE_TYPE_PASSIVE}
+         *            ).
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setSubscribeType(int subscribeType) {
+            if (subscribeType < SUBSCRIBE_TYPE_PASSIVE || subscribeType > SUBSCRIBE_TYPE_ACTIVE) {
+                throw new IllegalArgumentException("Invalid subscribeType - " + subscribeType);
+            }
+            mSubscribeType = subscribeType;
+            return this;
+        }
+
+        /**
+         * Sets the number of times an active (
+         * {@link SubscribeSettings.Builder#setSubscribeType(int)}) subscribe
+         * session will transmit a packet. When the count is reached an event
+         * will be generated for
+         * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with reason=
+         * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param subscribeCount Number of subscribe packets to transmit.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setSubscribeCount(int subscribeCount) {
+            if (subscribeCount < 0) {
+                throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
+            }
+            mSubscribeCount = subscribeCount;
+            return this;
+        }
+
+        /**
+         * Sets the time interval (in seconds) an active (
+         * {@link SubscribeSettings.Builder#setSubscribeType(int)}) subscribe
+         * session will be alive - i.e. transmitting a packet. When the TTL is
+         * reached an event will be generated for
+         * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with reason=
+         * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param ttlSec Lifetime of a subscribe session in seconds.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setTtlSec(int ttlSec) {
+            if (ttlSec < 0) {
+                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+            }
+            mTtlSec = ttlSec;
+            return this;
+        }
+
+        /**
+         * Build {@link SubscribeSettings} given the current requests made on
+         * the builder.
+         */
+        public SubscribeSettings build() {
+            return new SubscribeSettings(mSubscribeType, mSubscribeCount, mTtlSec);
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/TlvBufferUtils.java b/wifi/java/android/net/wifi/nan/TlvBufferUtils.java
new file mode 100644
index 0000000..ea8785a
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/TlvBufferUtils.java
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import libcore.io.Memory;
+
+import java.nio.BufferOverflowException;
+import java.nio.ByteOrder;
+import java.util.Iterator;
+
+/**
+ * Utility class to construct and parse byte arrays using the TLV format -
+ * Type/Length/Value format. The utilities accept a configuration of the size of
+ * the Type field and the Length field. A Type field size of 0 is allowed -
+ * allowing usage for LV (no T) array formats.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class TlvBufferUtils {
+    private TlvBufferUtils() {
+        // no reason to ever create this class
+    }
+
+    /**
+     * Utility class to construct byte arrays using the TLV format -
+     * Type/Length/Value.
+     * <p>
+     * A constructor is created specifying the size of the Type (T) and Length
+     * (L) fields. A specification of zero size T field is allowed - resulting
+     * in LV type format.
+     * <p>
+     * The byte array is either provided (using
+     * {@link TlvConstructor#wrap(byte[])}) or allocated (using
+     * {@link TlvConstructor#allocate(int)}).
+     * <p>
+     * Values are added to the structure using the {@code TlvConstructor.put*()}
+     * methods.
+     * <p>
+     * The final byte array is obtained using {@link TlvConstructor#getArray()}
+     * and {@link TlvConstructor#getActualLength()} methods.
+     */
+    public static class TlvConstructor {
+        private int mTypeSize;
+        private int mLengthSize;
+
+        private byte[] mArray;
+        private int mArrayLength;
+        private int mPosition;
+
+        /**
+         * Define a TLV constructor with the specified size of the Type (T) and
+         * Length (L) fields.
+         *
+         * @param typeSize Number of bytes used for the Type (T) field. Values
+         *            of 0, 1, or 2 bytes are allowed. A specification of 0
+         *            bytes implies that the field being constructed has the LV
+         *            format rather than the TLV format.
+         * @param lengthSize Number of bytes used for the Length (L) field.
+         *            Values of 1 or 2 bytes are allowed.
+         */
+        public TlvConstructor(int typeSize, int lengthSize) {
+            if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) {
+                throw new IllegalArgumentException(
+                        "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize);
+            }
+            mTypeSize = typeSize;
+            mLengthSize = lengthSize;
+        }
+
+        /**
+         * Set the byte array to be used to construct the TLV.
+         *
+         * @param array Byte array to be formatted.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor wrap(byte[] array) {
+            mArray = array;
+            mArrayLength = array.length;
+            return this;
+        }
+
+        /**
+         * Allocates a new byte array to be used ot construct a TLV.
+         *
+         * @param capacity The size of the byte array to be allocated.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor allocate(int capacity) {
+            mArray = new byte[capacity];
+            mArrayLength = capacity;
+            return this;
+        }
+
+        /**
+         * Copies a byte into the TLV with the indicated type. For an LV
+         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
+         * TlvConstructor(int, int)} ) the type field is ignored.
+         *
+         * @param type The value to be placed into the Type field.
+         * @param b The byte to be inserted into the structure.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor putByte(int type, byte b) {
+            checkLength(1);
+            addHeader(type, 1);
+            mArray[mPosition++] = b;
+            return this;
+        }
+
+        /**
+         * Copies a byte array into the TLV with the indicated type. For an LV
+         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
+         * TlvConstructor(int, int)} ) the type field is ignored.
+         *
+         * @param type The value to be placed into the Type field.
+         * @param array The array to be copied into the TLV structure.
+         * @param offset Start copying from the array at the specified offset.
+         * @param length Copy the specified number (length) of bytes from the
+         *            array.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor putByteArray(int type, byte[] array, int offset, int length) {
+            checkLength(length);
+            addHeader(type, length);
+            System.arraycopy(array, offset, mArray, mPosition, length);
+            mPosition += length;
+            return this;
+        }
+
+        /**
+         * Copies a byte array into the TLV with the indicated type. For an LV
+         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
+         * TlvConstructor(int, int)} ) the type field is ignored.
+         *
+         * @param type The value to be placed into the Type field.
+         * @param array The array to be copied (in full) into the TLV structure.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor putByteArray(int type, byte[] array) {
+            return putByteArray(type, array, 0, array.length);
+        }
+
+        /**
+         * Places a zero length element (i.e. Length field = 0) into the TLV.
+         * For an LV formatted structure (i.e. typeLength=0 in
+         * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is
+         * ignored.
+         *
+         * @param type The value to be placed into the Type field.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor putZeroLengthElement(int type) {
+            checkLength(0);
+            addHeader(type, 0);
+            return this;
+        }
+
+        /**
+         * Copies short into the TLV with the indicated type. For an LV
+         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
+         * TlvConstructor(int, int)} ) the type field is ignored.
+         *
+         * @param type The value to be placed into the Type field.
+         * @param data The short to be inserted into the structure.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor putShort(int type, short data) {
+            checkLength(2);
+            addHeader(type, 2);
+            Memory.pokeShort(mArray, mPosition, data, ByteOrder.BIG_ENDIAN);
+            mPosition += 2;
+            return this;
+        }
+
+        /**
+         * Copies integer into the TLV with the indicated type. For an LV
+         * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
+         * TlvConstructor(int, int)} ) the type field is ignored.
+         *
+         * @param type The value to be placed into the Type field.
+         * @param data The integer to be inserted into the structure.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor putInt(int type, int data) {
+            checkLength(4);
+            addHeader(type, 4);
+            Memory.pokeInt(mArray, mPosition, data, ByteOrder.BIG_ENDIAN);
+            mPosition += 4;
+            return this;
+        }
+
+        /**
+         * Copies a String's byte representation into the TLV with the indicated
+         * type. For an LV formatted structure (i.e. typeLength=0 in
+         * {@link TlvConstructor TlvConstructor(int, int)} ) the type field is
+         * ignored.
+         *
+         * @param type The value to be placed into the Type field.
+         * @param data The string whose bytes are to be inserted into the
+         *            structure.
+         * @return The constructor to facilitate chaining
+         *         {@code ctr.putXXX(..).putXXX(..)}.
+         */
+        public TlvConstructor putString(int type, String data) {
+            return putByteArray(type, data.getBytes(), 0, data.length());
+        }
+
+        /**
+         * Returns the constructed TLV formatted byte-array. Note that the
+         * returned array is the fully wrapped (
+         * {@link TlvConstructor#wrap(byte[])}) or allocated (
+         * {@link TlvConstructor#allocate(int)}) array - which isn't necessarily
+         * the actual size of the formatted data. Use
+         * {@link TlvConstructor#getActualLength()} to obtain the size of the
+         * formatted data.
+         *
+         * @return The byte array containing the TLV formatted structure.
+         */
+        public byte[] getArray() {
+            return mArray;
+        }
+
+        /**
+         * Returns the size of the TLV formatted portion of the wrapped or
+         * allocated byte array. The array itself is returned with
+         * {@link TlvConstructor#getArray()}.
+         *
+         * @return The size of the TLV formatted portion of the byte array.
+         */
+        public int getActualLength() {
+            return mPosition;
+        }
+
+        private void checkLength(int dataLength) {
+            if (mPosition + mTypeSize + mLengthSize + dataLength > mArrayLength) {
+                throw new BufferOverflowException();
+            }
+        }
+
+        private void addHeader(int type, int length) {
+            if (mTypeSize == 1) {
+                mArray[mPosition] = (byte) type;
+            } else if (mTypeSize == 2) {
+                Memory.pokeShort(mArray, mPosition, (short) type, ByteOrder.BIG_ENDIAN);
+            }
+            mPosition += mTypeSize;
+
+            if (mLengthSize == 1) {
+                mArray[mPosition] = (byte) length;
+            } else if (mLengthSize == 2) {
+                Memory.pokeShort(mArray, mPosition, (short) length, ByteOrder.BIG_ENDIAN);
+            }
+            mPosition += mLengthSize;
+        }
+    }
+
+    /**
+     * Utility class used when iterating over a TLV formatted byte-array. Use
+     * {@link TlvIterable} to iterate over array. A {@link TlvElement}
+     * represents each entry in a TLV formatted byte-array.
+     */
+    public static class TlvElement {
+        /**
+         * The Type (T) field of the current TLV element. Note that for LV
+         * formatted byte-arrays (i.e. TLV whose Type/T size is 0) the value of
+         * this field is undefined.
+         */
+        public int mType;
+
+        /**
+         * The Length (L) field of the current TLV element.
+         */
+        public int mLength;
+
+        /**
+         * The Value (V) field - a raw byte array representing the current TLV
+         * element where the entry starts at {@link TlvElement#mOffset}.
+         */
+        public byte[] mRefArray;
+
+        /**
+         * The offset to be used into {@link TlvElement#mRefArray} to access the
+         * raw data representing the current TLV element.
+         */
+        public int mOffset;
+
+        private TlvElement(int type, int length, byte[] refArray, int offset) {
+            mType = type;
+            mLength = length;
+            mRefArray = refArray;
+            mOffset = offset;
+        }
+
+        /**
+         * Utility function to return a byte representation of a TLV element of
+         * length 1. Note: an attempt to call this function on a TLV item whose
+         * {@link TlvElement#mLength} is != 1 will result in an exception.
+         *
+         * @return byte representation of current TLV element.
+         */
+        public byte getByte() {
+            if (mLength != 1) {
+                throw new IllegalArgumentException(
+                        "Accesing a byte from a TLV element of length " + mLength);
+            }
+            return mRefArray[mOffset];
+        }
+
+        /**
+         * Utility function to return a short representation of a TLV element of
+         * length 2. Note: an attempt to call this function on a TLV item whose
+         * {@link TlvElement#mLength} is != 2 will result in an exception.
+         *
+         * @return short representation of current TLV element.
+         */
+        public short getShort() {
+            if (mLength != 2) {
+                throw new IllegalArgumentException(
+                        "Accesing a short from a TLV element of length " + mLength);
+            }
+            return Memory.peekShort(mRefArray, mOffset, ByteOrder.BIG_ENDIAN);
+        }
+
+        /**
+         * Utility function to return an integer representation of a TLV element
+         * of length 4. Note: an attempt to call this function on a TLV item
+         * whose {@link TlvElement#mLength} is != 4 will result in an exception.
+         *
+         * @return integer representation of current TLV element.
+         */
+        public int getInt() {
+            if (mLength != 4) {
+                throw new IllegalArgumentException(
+                        "Accesing an int from a TLV element of length " + mLength);
+            }
+            return Memory.peekInt(mRefArray, mOffset, ByteOrder.BIG_ENDIAN);
+        }
+
+        /**
+         * Utility function to return a String representation of a TLV element.
+         *
+         * @return String repersentation of the current TLV element.
+         */
+        public String getString() {
+            return new String(mRefArray, mOffset, mLength);
+        }
+    }
+
+    /**
+     * Utility class to iterate over a TLV formatted byte-array.
+     */
+    public static class TlvIterable implements Iterable<TlvElement> {
+        private int mTypeSize;
+        private int mLengthSize;
+        private byte[] mArray;
+        private int mArrayLength;
+
+        /**
+         * Constructs a TlvIterable object - specifying the format of the TLV
+         * (the sizes of the Type and Length fields), and the byte array whose
+         * data is to be parsed.
+         *
+         * @param typeSize Number of bytes used for the Type (T) field. Valid
+         *            values are 0 (i.e. indicating the format is LV rather than
+         *            TLV), 1, and 2 bytes.
+         * @param lengthSize Number of bytes sued for the Length (L) field.
+         *            Values values are 1 or 2 bytes.
+         * @param array The TLV formatted byte-array to parse.
+         * @param length The number of bytes of the array to be used in the
+         *            parsing.
+         */
+        public TlvIterable(int typeSize, int lengthSize, byte[] array, int length) {
+            if (typeSize < 0 || typeSize > 2 || lengthSize <= 0 || lengthSize > 2) {
+                throw new IllegalArgumentException(
+                        "Invalid sizes - typeSize=" + typeSize + ", lengthSize=" + lengthSize);
+            }
+            mTypeSize = typeSize;
+            mLengthSize = lengthSize;
+            mArray = array;
+            mArrayLength = length;
+        }
+
+        /**
+         * Prints out a parsed representation of the TLV-formatted byte array.
+         * Whenever possible bytes, shorts, and integer are printed out (for
+         * fields whose length is 1, 2, or 4 respectively).
+         */
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+
+            builder.append("[");
+            boolean first = true;
+            for (TlvElement tlv : this) {
+                if (!first) {
+                    builder.append(",");
+                }
+                first = false;
+                builder.append(" (");
+                if (mTypeSize != 0) {
+                    builder.append("T=" + tlv.mType + ",");
+                }
+                builder.append("L=" + tlv.mLength + ") ");
+                if (tlv.mLength == 0) {
+                    builder.append("<null>");
+                } else if (tlv.mLength == 1) {
+                    builder.append(tlv.getByte());
+                } else if (tlv.mLength == 2) {
+                    builder.append(tlv.getShort());
+                } else if (tlv.mLength == 4) {
+                    builder.append(tlv.getInt());
+                } else {
+                    builder.append("<bytes>");
+                }
+                if (tlv.mLength != 0) {
+                    builder.append(" (S='" + tlv.getString() + "')");
+                }
+            }
+            builder.append("]");
+
+            return builder.toString();
+        }
+
+        /**
+         * Returns an iterator to step through a TLV formatted byte-array. The
+         * individual elements returned by the iterator are {@link TlvElement}.
+         */
+        @Override
+        public Iterator<TlvElement> iterator() {
+            return new Iterator<TlvElement>() {
+                private int mOffset = 0;
+
+                @Override
+                public boolean hasNext() {
+                    return mOffset < mArrayLength;
+                }
+
+                @Override
+                public TlvElement next() {
+                    int type = 0;
+                    if (mTypeSize == 1) {
+                        type = mArray[mOffset];
+                    } else if (mTypeSize == 2) {
+                        type = Memory.peekShort(mArray, mOffset, ByteOrder.BIG_ENDIAN);
+                    }
+                    mOffset += mTypeSize;
+
+                    int length = 0;
+                    if (mLengthSize == 1) {
+                        length = mArray[mOffset];
+                    } else if (mLengthSize == 2) {
+                        length = Memory.peekShort(mArray, mOffset, ByteOrder.BIG_ENDIAN);
+                    }
+                    mOffset += mLengthSize;
+
+                    TlvElement tlv = new TlvElement(type, length, mArray, mOffset);
+                    mOffset += length;
+                    return tlv;
+                }
+
+                @Override
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java b/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
new file mode 100644
index 0000000..eae0a55
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanEventListener.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 android.net.wifi.nan;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * Base class for NAN events callbacks. Should be extended by applications
+ * wanting notifications. These are callbacks applying to the NAN connection as
+ * a whole - not to specific publish or subscribe sessions - for that see
+ * {@link WifiNanSessionListener}.
+ * <p>
+ * During registration specify which specific events are desired using a set of
+ * {@code NanEventListener.LISTEN_*} flags OR'd together. Only those events will
+ * be delivered to the registered listener. Override those callbacks
+ * {@code NanEventListener.on*} for the registered events.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanEventListener {
+    private static final String TAG = "WifiNanEventListener";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false; // STOPSHIP if true
+
+    /**
+     * Configuration completion callback event registration flag. Corresponding
+     * callback is {@link WifiNanEventListener#onConfigCompleted(ConfigRequest)}.
+     */
+    public static final int LISTEN_CONFIG_COMPLETED = 0x1 << 0;
+
+    /**
+     * Configuration failed callback event registration flag. Corresponding
+     * callback is {@link WifiNanEventListener#onConfigFailed(int)}.
+     */
+    public static final int LISTEN_CONFIG_FAILED = 0x1 << 1;
+
+    /**
+     * NAN cluster is down callback event registration flag. Corresponding
+     * callback is {@link WifiNanEventListener#onNanDown(int)}.
+     */
+    public static final int LISTEN_NAN_DOWN = 0x1 << 2;
+
+    /**
+     * NAN identity has changed event registration flag. This may be due to
+     * joining a cluster, starting a cluster, or discovery interface change. The
+     * implication is that peers you've been communicating with may no longer
+     * recognize you and you need to re-establish your identity. Corresponding
+     * callback is {@link WifiNanEventListener#onIdentityChanged()}.
+     */
+    public static final int LISTEN_IDENTITY_CHANGED = 0x1 << 3;
+
+    private final Handler mHandler;
+
+    /**
+     * Constructs a {@link WifiNanEventListener} using the looper of the current
+     * thread. I.e. all callbacks will be delivered on the current thread.
+     */
+    public WifiNanEventListener() {
+        this(Looper.myLooper());
+    }
+
+    /**
+     * Constructs a {@link WifiNanEventListener} using the specified looper. I.e.
+     * all callbacks will delivered on the thread of the specified looper.
+     *
+     * @param looper The looper on which to execute the callbacks.
+     */
+    public WifiNanEventListener(Looper looper) {
+        if (VDBG) Log.v(TAG, "ctor: looper=" + looper);
+        mHandler = new Handler(looper) {
+            @Override
+            public void handleMessage(Message msg) {
+                if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
+                switch (msg.what) {
+                    case LISTEN_CONFIG_COMPLETED:
+                        WifiNanEventListener.this.onConfigCompleted((ConfigRequest) msg.obj);
+                        break;
+                    case LISTEN_CONFIG_FAILED:
+                        WifiNanEventListener.this.onConfigFailed(msg.arg1);
+                        break;
+                    case LISTEN_NAN_DOWN:
+                        WifiNanEventListener.this.onNanDown(msg.arg1);
+                        break;
+                    case LISTEN_IDENTITY_CHANGED:
+                        WifiNanEventListener.this.onIdentityChanged();
+                        break;
+                }
+            }
+        };
+    }
+
+    /**
+     * Called when NAN configuration is completed. Event will only be delivered
+     * if registered using {@link WifiNanEventListener#LISTEN_CONFIG_COMPLETED}. A
+     * dummy (empty implementation printing out a warning). Make sure to
+     * override if registered.
+     *
+     * @param completedConfig The actual configuration request which was
+     *            completed. Note that it may be different from that requested
+     *            by the application. The service combines configuration
+     *            requests from all applications.
+     */
+    public void onConfigCompleted(ConfigRequest completedConfig) {
+        Log.w(TAG, "onConfigCompleted: called in stub - override if interested or disable");
+    }
+
+    /**
+     * Called when NAN configuration failed. Event will only be delivered if
+     * registered using {@link WifiNanEventListener#LISTEN_CONFIG_FAILED}. A dummy
+     * (empty implementation printing out a warning). Make sure to override if
+     * registered.
+     *
+     * @param reason Failure reason code, see {@code NanSessionListener.FAIL_*}.
+     */
+    public void onConfigFailed(int reason) {
+        Log.w(TAG, "onConfigFailed: called in stub - override if interested or disable");
+    }
+
+    /**
+     * Called when NAN cluster is down. Event will only be delivered if
+     * registered using {@link WifiNanEventListener#LISTEN_NAN_DOWN}. A dummy (empty
+     * implementation printing out a warning). Make sure to override if
+     * registered.
+     *
+     * @param reason Reason code for event, see {@code NanSessionListener.FAIL_*}.
+     */
+    public void onNanDown(int reason) {
+        Log.w(TAG, "onNanDown: called in stub - override if interested or disable");
+    }
+
+    /**
+     * Called when NAN identity has changed. This may be due to joining a
+     * cluster, starting a cluster, or discovery interface change. The
+     * implication is that peers you've been communicating with may no longer
+     * recognize you and you need to re-establish your identity. Event will only
+     * be delivered if registered using
+     * {@link WifiNanEventListener#LISTEN_IDENTITY_CHANGED}. A dummy (empty
+     * implementation printing out a warning). Make sure to override if
+     * registered.
+     */
+    public void onIdentityChanged() {
+        if (VDBG) Log.v(TAG, "onIdentityChanged: called in stub - override if interested");
+    }
+
+    /**
+     * {@hide}
+     */
+    public IWifiNanEventListener callback = new IWifiNanEventListener.Stub() {
+        @Override
+        public void onConfigCompleted(ConfigRequest completedConfig) {
+            if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);
+
+            Message msg = mHandler.obtainMessage(LISTEN_CONFIG_COMPLETED);
+            msg.obj = completedConfig;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onConfigFailed(int reason) {
+            if (VDBG) Log.v(TAG, "onConfigFailed: reason=" + reason);
+
+            Message msg = mHandler.obtainMessage(LISTEN_CONFIG_FAILED);
+            msg.arg1 = reason;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onNanDown(int reason) {
+            if (VDBG) Log.v(TAG, "onNanDown: reason=" + reason);
+
+            Message msg = mHandler.obtainMessage(LISTEN_NAN_DOWN);
+            msg.arg1 = reason;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onIdentityChanged() {
+            if (VDBG) Log.v(TAG, "onIdentityChanged");
+
+            Message msg = mHandler.obtainMessage(LISTEN_IDENTITY_CHANGED);
+            mHandler.sendMessage(msg);
+        }
+    };
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/nan/WifiNanManager.java
new file mode 100644
index 0000000..877f993
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanManager.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * This class provides the primary API for managing Wi-Fi NAN operation:
+ * including discovery and data-links. Get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(String)
+ * Context.getSystemService(Context.WIFI_NAN_SERVICE)}.
+ * <p>
+ * The class provides access to:
+ * <ul>
+ * <li>Configure a NAN connection and register for events.
+ * <li>Create publish and subscribe sessions.
+ * <li>Create NAN network specifier to be used to create a NAN network.
+ * </ul>
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanManager {
+    private static final String TAG = "WifiNanManager";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false; // STOPSHIP if true
+
+    private IBinder mBinder;
+
+    private IWifiNanManager mService;
+
+    /**
+     * {@hide}
+     */
+    public WifiNanManager(IWifiNanManager service) {
+        mService = service;
+    }
+
+    /**
+     * Re-connect to the Wi-Fi NAN service - enabling the application to execute
+     * {@link WifiNanManager} APIs. Application don't normally need to call this
+     * API since it is executed in the constructor. However, applications which
+     * have explicitly {@link WifiNanManager#disconnect()} need to call this
+     * function to re-connect.
+     *
+     * @param listener A listener extended from {@link WifiNanEventListener}.
+     * @param events The set of events to be delivered to the {@code listener}.
+     *            OR'd event flags from {@link WifiNanEventListener
+     *            NanEventListener.LISTEN*}.
+     */
+    public void connect(WifiNanEventListener listener, int events) {
+        try {
+            if (VDBG) Log.v(TAG, "connect()");
+            if (listener == null) {
+                throw new IllegalArgumentException("Invalid listener - must not be null");
+            }
+            if (mBinder == null) {
+                mBinder = new Binder();
+            }
+            mService.connect(mBinder, listener.callback, events);
+        } catch (RemoteException e) {
+            Log.w(TAG, "connect RemoteException (FYI - ignoring): " + e);
+        }
+    }
+
+    /**
+     * Disconnect from the Wi-Fi NAN service and destroy all outstanding
+     * operations - i.e. all publish and subscribes are terminated, any
+     * outstanding data-link is shut-down, and all requested NAN configurations
+     * are cancelled.
+     * <p>
+     * An application may then re-connect using
+     * {@link WifiNanManager#connect(WifiNanEventListener, int)} .
+     */
+    public void disconnect() {
+        try {
+            if (VDBG) Log.v(TAG, "disconnect()");
+            mService.disconnect(mBinder);
+            mBinder = null;
+        } catch (RemoteException e) {
+            Log.w(TAG, "disconnect RemoteException (FYI - ignoring): " + e);
+        }
+    }
+
+    /**
+     * Requests a NAN configuration, specified by {@link ConfigRequest}. Note
+     * that NAN is a shared resource and the device can only be a member of a
+     * single cluster. Thus the service may merge configuration requests from
+     * multiple applications and configure NAN differently from individual
+     * requests.
+     * <p>
+     * The {@link WifiNanEventListener#onConfigCompleted(ConfigRequest)} will be
+     * called when configuration is completed (if a listener is registered for
+     * this specific event).
+     *
+     * @param configRequest The requested NAN configuration.
+     */
+    public void requestConfig(ConfigRequest configRequest) {
+        if (VDBG) Log.v(TAG, "requestConfig(): configRequest=" + configRequest);
+        try {
+            mService.requestConfig(configRequest);
+        } catch (RemoteException e) {
+            Log.w(TAG, "requestConfig RemoteException (FYI - ignoring): " + e);
+        }
+    }
+
+    /**
+     * Request a NAN publish session. The results of the publish session
+     * operation will result in callbacks to the indicated listener:
+     * {@link WifiNanSessionListener NanSessionListener.on*}.
+     *
+     * @param publishData The {@link PublishData} specifying the contents of the
+     *            publish session.
+     * @param publishSettings The {@link PublishSettings} specifying the
+     *            settings for the publish session.
+     * @param listener The {@link WifiNanSessionListener} derived objects to be used
+     *            for the event callbacks specified by {@code events}.
+     * @param events The list of events to be delivered to the {@code listener}
+     *            object. An OR'd value of {@link WifiNanSessionListener
+     *            NanSessionListener.LISTEN_*}.
+     * @return The {@link WifiNanPublishSession} which can be used to further
+     *         control the publish session.
+     */
+    public WifiNanPublishSession publish(PublishData publishData, PublishSettings publishSettings,
+            WifiNanSessionListener listener, int events) {
+        return publishRaw(publishData, publishSettings, listener,
+                events | WifiNanSessionListener.LISTEN_HIDDEN_FLAGS);
+    }
+
+    /**
+     * Same as publish(*) but does not modify the event flag
+     *
+     * @hide
+     */
+    public WifiNanPublishSession publishRaw(PublishData publishData,
+            PublishSettings publishSettings, WifiNanSessionListener listener, int events) {
+        if (VDBG) Log.v(TAG, "publish(): data='" + publishData + "', settings=" + publishSettings);
+
+        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED
+                && publishData.mRxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish data & settings: UNSOLICITED "
+                    + "publishes (active) can't have an Rx filter");
+        }
+        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_SOLICITED
+                && publishData.mTxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish data & settings: SOLICITED "
+                    + "publishes (passive) can't have a Tx filter");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("Invalid listener - must not be null");
+        }
+
+        int sessionId;
+
+        try {
+            sessionId = mService.createSession(listener.callback, events);
+            if (DBG) Log.d(TAG, "publish: session created - sessionId=" + sessionId);
+            mService.publish(sessionId, publishData, publishSettings);
+        } catch (RemoteException e) {
+            Log.w(TAG, "createSession/publish RemoteException: " + e);
+            return null;
+        }
+
+        return new WifiNanPublishSession(this, sessionId);
+    }
+
+    /**
+     * {@hide}
+     */
+    public void publish(int sessionId, PublishData publishData, PublishSettings publishSettings) {
+        if (VDBG) Log.v(TAG, "publish(): data='" + publishData + "', settings=" + publishSettings);
+
+        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED
+                && publishData.mRxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish data & settings: UNSOLICITED "
+                    + "publishes (active) can't have an Rx filter");
+        }
+        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_SOLICITED
+                && publishData.mTxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish data & settings: SOLICITED "
+                    + "publishes (passive) can't have a Tx filter");
+        }
+
+        try {
+            mService.publish(sessionId, publishData, publishSettings);
+        } catch (RemoteException e) {
+            Log.w(TAG, "publish RemoteException: " + e);
+        }
+    }
+    /**
+     * Request a NAN subscribe session. The results of the subscribe session
+     * operation will result in callbacks to the indicated listener:
+     * {@link WifiNanSessionListener NanSessionListener.on*}.
+     *
+     * @param subscribeData The {@link SubscribeData} specifying the contents of
+     *            the subscribe session.
+     * @param subscribeSettings The {@link SubscribeSettings} specifying the
+     *            settings for the subscribe session.
+     * @param listener The {@link WifiNanSessionListener} derived objects to be used
+     *            for the event callbacks specified by {@code events}.
+     * @param events The list of events to be delivered to the {@code listener}
+     *            object. An OR'd value of {@link WifiNanSessionListener
+     *            NanSessionListener.LISTEN_*}.
+     * @return The {@link WifiNanSubscribeSession} which can be used to further
+     *         control the subscribe session.
+     */
+    public WifiNanSubscribeSession subscribe(SubscribeData subscribeData,
+            SubscribeSettings subscribeSettings,
+            WifiNanSessionListener listener, int events) {
+        return subscribeRaw(subscribeData, subscribeSettings, listener,
+                events | WifiNanSessionListener.LISTEN_HIDDEN_FLAGS);
+    }
+
+    /**
+     * Same as subscribe(*) but does not modify the event flag
+     *
+     * @hide
+     */
+    public WifiNanSubscribeSession subscribeRaw(SubscribeData subscribeData,
+            SubscribeSettings subscribeSettings, WifiNanSessionListener listener, int events) {
+        if (VDBG) {
+            Log.v(TAG, "subscribe(): data='" + subscribeData + "', settings=" + subscribeSettings);
+        }
+
+        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE
+                && subscribeData.mRxFilterLength != 0) {
+            throw new IllegalArgumentException(
+                    "Invalid subscribe data & settings: ACTIVE subscribes can't have an Rx filter");
+        }
+        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE
+                && subscribeData.mTxFilterLength != 0) {
+            throw new IllegalArgumentException(
+                    "Invalid subscribe data & settings: PASSIVE subscribes can't have a Tx filter");
+        }
+
+        int sessionId;
+
+        try {
+            sessionId = mService.createSession(listener.callback, events);
+            if (DBG) Log.d(TAG, "subscribe: session created - sessionId=" + sessionId);
+            mService.subscribe(sessionId, subscribeData, subscribeSettings);
+        } catch (RemoteException e) {
+            Log.w(TAG, "createSession/subscribe RemoteException: " + e);
+            return null;
+        }
+
+        return new WifiNanSubscribeSession(this, sessionId);
+    }
+
+    /**
+     * {@hide}
+     */
+    public void subscribe(int sessionId, SubscribeData subscribeData,
+            SubscribeSettings subscribeSettings) {
+        if (VDBG) {
+            Log.v(TAG, "subscribe(): data='" + subscribeData + "', settings=" + subscribeSettings);
+        }
+
+        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE
+                && subscribeData.mRxFilterLength != 0) {
+            throw new IllegalArgumentException(
+                    "Invalid subscribe data & settings: ACTIVE subscribes can't have an Rx filter");
+        }
+        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE
+                && subscribeData.mTxFilterLength != 0) {
+            throw new IllegalArgumentException(
+                    "Invalid subscribe data & settings: PASSIVE subscribes can't have a Tx filter");
+        }
+
+        try {
+            mService.subscribe(sessionId, subscribeData, subscribeSettings);
+        } catch (RemoteException e) {
+            Log.w(TAG, "subscribe RemoteException: " + e);
+        }
+    }
+
+    /**
+     * {@hide}
+     */
+    public void stopSession(int sessionId) {
+        if (DBG) Log.d(TAG, "Stop NAN session #" + sessionId);
+
+        try {
+            mService.stopSession(sessionId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "stopSession RemoteException (FYI - ignoring): " + e);
+        }
+    }
+
+    /**
+     * {@hide}
+     */
+    public void destroySession(int sessionId) {
+        if (DBG) Log.d(TAG, "Destroy NAN session #" + sessionId);
+
+        try {
+            mService.destroySession(sessionId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "destroySession RemoteException (FYI - ignoring): " + e);
+        }
+    }
+
+    /**
+     * {@hide}
+     */
+    public void sendMessage(int sessionId, int peerId, byte[] message, int messageLength) {
+        try {
+            if (VDBG) {
+                Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
+                        + ", messageLength=" + messageLength);
+            }
+            mService.sendMessage(sessionId, peerId, message, messageLength);
+        } catch (RemoteException e) {
+            Log.w(TAG, "subscribe RemoteException (FYI - ignoring): " + e);
+        }
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java b/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
new file mode 100644
index 0000000..81b38f4
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+/**
+ * A representation of a NAN publish session. Created when
+ * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
+ * is executed. The object can be used to stop and re-start (re-configure) the
+ * publish session.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanPublishSession extends WifiNanSession {
+    /**
+     * {@hide}
+     */
+    public WifiNanPublishSession(WifiNanManager manager, int sessionId) {
+        super(manager, sessionId);
+    }
+
+    /**
+     * Restart/re-configure the publish session. Note that the
+     * {@link WifiNanSessionListener} is not replaced - the same listener used at
+     * creation is still used.
+     *
+     * @param publishData The data ({@link PublishData}) to publish.
+     * @param publishSettings The settings ({@link PublishSettings}) of the
+     *            publish session.
+     */
+    public void publish(PublishData publishData, PublishSettings publishSettings) {
+        mManager.publish(mSessionId, publishData, publishSettings);
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSession.java b/wifi/java/android/net/wifi/nan/WifiNanSession.java
new file mode 100644
index 0000000..c6b384e
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanSession.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.util.Log;
+
+/**
+ * A representation of a single publish or subscribe NAN session. This object
+ * will not be created directly - only its child classes are available:
+ * {@link WifiNanPublishSession} and {@link WifiNanSubscribeSession}.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanSession {
+    private static final String TAG = "WifiNanSession";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false; // STOPSHIP if true
+
+    /**
+     * {@hide}
+     */
+    protected WifiNanManager mManager;
+
+    /**
+     * {@hide}
+     */
+    protected int mSessionId;
+
+    /**
+     * {@hide}
+     */
+    private boolean mDestroyed;
+
+    /**
+     * {@hide}
+     */
+    public WifiNanSession(WifiNanManager manager, int sessionId) {
+        if (VDBG) Log.v(TAG, "New client created: manager=" + manager + ", sessionId=" + sessionId);
+
+        mManager = manager;
+        mSessionId = sessionId;
+        mDestroyed = false;
+    }
+
+    /**
+     * Terminate the current publish or subscribe session - i.e. stop
+     * transmitting packet on-air (for an active session) or listening for
+     * matches (for a passive session). Note that the session may still receive
+     * incoming messages and may be re-configured/re-started at a later time.
+     */
+    public void stop() {
+        mManager.stopSession(mSessionId);
+    }
+
+    /**
+     * Destroy the current publish or subscribe session. Performs a
+     * {@link WifiNanSession#stop()} function but in addition destroys the session -
+     * it will not be able to receive any messages or to be restarted at a later
+     * time.
+     */
+    public void destroy() {
+        mManager.destroySession(mSessionId);
+        mDestroyed = true;
+    }
+
+    /**
+     * {@hide}
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        if (!mDestroyed) {
+            Log.w(TAG, "WifiNanSession mSessionId=" + mSessionId
+                            + " was not explicitly destroyed. The session may use resources until "
+                            + "destroyed so step should be done explicitly");
+        }
+        destroy();
+    }
+
+    /**
+     * Sends a message to the specified destination. Message transmission is
+     * part of the current discovery session - i.e. executed subsequent to a
+     * publish/subscribe
+     * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}
+     * event.
+     *
+     * @param peerId The peer's ID for the message. Must be a result of an
+     *            {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}
+     *            event.
+     * @param message The message to be transmitted.
+     * @param messageLength The number of bytes from the {@code message} to be
+     *            transmitted.
+     */
+    public void sendMessage(int peerId, byte[] message, int messageLength) {
+        mManager.sendMessage(mSessionId, peerId, message, messageLength);
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java b/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
new file mode 100644
index 0000000..c9d08c7
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * Base class for NAN session events callbacks. Should be extended by
+ * applications wanting notifications. The callbacks are registered when a
+ * publish or subscribe session is created using
+ * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
+ * or
+ * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
+ * . These are callbacks applying to a specific NAN session. Events
+ * corresponding to the NAN link are delivered using {@link WifiNanEventListener}.
+ * <p>
+ * A single listener is registered at session creation - it cannot be replaced.
+ * <p>
+ * During registration specify which specific events are desired using a set of
+ * {@code NanSessionListener.LISTEN_*} flags OR'd together. Only those events
+ * will be delivered to the registered listener. Override those callbacks
+ * {@code NanSessionListener.on*} for the registered events.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanSessionListener {
+    private static final String TAG = "WifiNanSessionListener";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false; // STOPSHIP if true
+
+    /**
+     * Publish fail callback event registration flag. Corresponding callback is
+     * {@link WifiNanSessionListener#onPublishFail(int)}.
+     *
+     * @hide
+     */
+    public static final int LISTEN_PUBLISH_FAIL = 0x1 << 0;
+
+    /**
+     * Publish terminated callback event registration flag. Corresponding
+     * callback is {@link WifiNanSessionListener#onPublishTerminated(int)}.
+     */
+    public static final int LISTEN_PUBLISH_TERMINATED = 0x1 << 1;
+
+    /**
+     * Subscribe fail callback event registration flag. Corresponding callback
+     * is {@link WifiNanSessionListener#onSubscribeFail(int)}.
+     *
+     * @hide
+     */
+    public static final int LISTEN_SUBSCRIBE_FAIL = 0x1 << 2;
+
+    /**
+     * Subscribe terminated callback event registration flag. Corresponding
+     * callback is {@link WifiNanSessionListener#onSubscribeTerminated(int)}.
+     */
+    public static final int LISTEN_SUBSCRIBE_TERMINATED = 0x1 << 3;
+
+    /**
+     * Match (discovery: publish or subscribe) callback event registration flag.
+     * Corresponding callback is
+     * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}.
+     *
+     * @hide
+     */
+    public static final int LISTEN_MATCH = 0x1 << 4;
+
+    /**
+     * Message sent successfully callback event registration flag. Corresponding
+     * callback is {@link WifiNanSessionListener#onMessageSendSuccess()}.
+     *
+     * @hide
+     */
+    public static final int LISTEN_MESSAGE_SEND_SUCCESS = 0x1 << 5;
+
+    /**
+     * Message sending failure callback event registration flag. Corresponding
+     * callback is {@link WifiNanSessionListener#onMessageSendFail(int)}.
+     *
+     * @hide
+     */
+    public static final int LISTEN_MESSAGE_SEND_FAIL = 0x1 << 6;
+
+    /**
+     * Message received callback event registration flag. Corresponding callback
+     * is {@link WifiNanSessionListener#onMessageReceived(int, byte[], int)}.
+     *
+     * @hide
+     */
+    public static final int LISTEN_MESSAGE_RECEIVED = 0x1 << 7;
+
+    /**
+     * List of hidden events: which are mandatory - i.e. they will be added to
+     * every request.
+     *
+     * @hide
+     */
+    public static final int LISTEN_HIDDEN_FLAGS = LISTEN_PUBLISH_FAIL | LISTEN_SUBSCRIBE_FAIL
+            | LISTEN_MATCH | LISTEN_MESSAGE_SEND_SUCCESS | LISTEN_MESSAGE_SEND_FAIL
+            | LISTEN_MESSAGE_RECEIVED;
+
+    /**
+     * Failure reason flag for {@link WifiNanEventListener} and
+     * {@link WifiNanSessionListener} callbacks. Indicates no resources to execute
+     * the requested operation.
+     */
+    public static final int FAIL_REASON_NO_RESOURCES = 0;
+
+    /**
+     * Failure reason flag for {@link WifiNanEventListener} and
+     * {@link WifiNanSessionListener} callbacks. Indicates invalid argument in the
+     * requested operation.
+     */
+    public static final int FAIL_REASON_INVALID_ARGS = 1;
+
+    /**
+     * Failure reason flag for {@link WifiNanEventListener} and
+     * {@link WifiNanSessionListener} callbacks. Indicates a message is transmitted
+     * without a match (i.e. a discovery) occurring first.
+     */
+    public static final int FAIL_REASON_NO_MATCH_SESSION = 2;
+
+    /**
+     * Failure reason flag for {@link WifiNanEventListener} and
+     * {@link WifiNanSessionListener} callbacks. Indicates an unspecified error
+     * occurred during the operation.
+     */
+    public static final int FAIL_REASON_OTHER = 3;
+
+    /**
+     * Failure reason flag for
+     * {@link WifiNanSessionListener#onPublishTerminated(int)} and
+     * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks.
+     * Indicates that publish or subscribe session is done - i.e. all the
+     * requested operations (per {@link PublishSettings} or
+     * {@link SubscribeSettings}) have been executed.
+     */
+    public static final int TERMINATE_REASON_DONE = 0;
+
+    /**
+     * Failure reason flag for
+     * {@link WifiNanSessionListener#onPublishTerminated(int)} and
+     * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks.
+     * Indicates that publish or subscribe session is terminated due to a
+     * failure.
+     */
+    public static final int TERMINATE_REASON_FAIL = 1;
+
+    private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id";
+    private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
+    private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
+
+    private final Handler mHandler;
+
+    /**
+     * Constructs a {@link WifiNanSessionListener} using the looper of the current
+     * thread. I.e. all callbacks will be delivered on the current thread.
+     */
+    public WifiNanSessionListener() {
+        this(Looper.myLooper());
+    }
+
+    /**
+     * Constructs a {@link WifiNanSessionListener} using the specified looper. I.e.
+     * all callbacks will delivered on the thread of the specified looper.
+     *
+     * @param looper The looper on which to execute the callbacks.
+     */
+    public WifiNanSessionListener(Looper looper) {
+        if (VDBG) Log.v(TAG, "ctor: looper=" + looper);
+        mHandler = new Handler(looper) {
+            @Override
+            public void handleMessage(Message msg) {
+                if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
+                switch (msg.what) {
+                    case LISTEN_PUBLISH_FAIL:
+                        WifiNanSessionListener.this.onPublishFail(msg.arg1);
+                        break;
+                    case LISTEN_PUBLISH_TERMINATED:
+                        WifiNanSessionListener.this.onPublishTerminated(msg.arg1);
+                        break;
+                    case LISTEN_SUBSCRIBE_FAIL:
+                        WifiNanSessionListener.this.onSubscribeFail(msg.arg1);
+                        break;
+                    case LISTEN_SUBSCRIBE_TERMINATED:
+                        WifiNanSessionListener.this.onSubscribeTerminated(msg.arg1);
+                        break;
+                    case LISTEN_MATCH:
+                        WifiNanSessionListener.this.onMatch(
+                                msg.getData().getInt(MESSAGE_BUNDLE_KEY_PEER_ID),
+                                msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1,
+                                msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2), msg.arg2);
+                        break;
+                    case LISTEN_MESSAGE_SEND_SUCCESS:
+                        WifiNanSessionListener.this.onMessageSendSuccess();
+                        break;
+                    case LISTEN_MESSAGE_SEND_FAIL:
+                        WifiNanSessionListener.this.onMessageSendFail(msg.arg1);
+                        break;
+                    case LISTEN_MESSAGE_RECEIVED:
+                        WifiNanSessionListener.this.onMessageReceived(msg.arg2,
+                                msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1);
+                        break;
+                }
+            }
+        };
+    }
+
+    /**
+     * Called when a publish operation fails. It is dummy method (empty
+     * implementation printing out a log message). Override to implement your
+     * custom response.
+     *
+     * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
+     *            codes.
+     */
+    public void onPublishFail(int reason) {
+        if (VDBG) Log.v(TAG, "onPublishFail: called in stub - override if interested");
+    }
+
+    /**
+     * Called when a publish operation terminates. Event will only be delivered
+     * if registered using {@link WifiNanSessionListener#LISTEN_PUBLISH_TERMINATED}.
+     * A dummy (empty implementation printing out a warning). Make sure to
+     * override if registered.
+     *
+     * @param reason The termination reason using
+     *            {@code NanSessionListener.TERMINATE_*} codes.
+     */
+    public void onPublishTerminated(int reason) {
+        Log.w(TAG, "onPublishTerminated: called in stub - override if interested or disable");
+    }
+
+    /**
+     * Called when a subscribe operation fails. It is dummy method (empty
+     * implementation printing out a log message). Override to implement your
+     * custom response.
+     *
+     * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
+     *            codes.
+     */
+    public void onSubscribeFail(int reason) {
+        if (VDBG) Log.v(TAG, "onSubscribeFail: called in stub - override if interested");
+    }
+
+    /**
+     * Called when a subscribe operation terminates. Event will only be
+     * delivered if registered using
+     * {@link WifiNanSessionListener#LISTEN_SUBSCRIBE_TERMINATED}. A dummy (empty
+     * implementation printing out a warning). Make sure to override if
+     * registered.
+     *
+     * @param reason The termination reason using
+     *            {@code NanSessionListener.TERMINATE_*} codes.
+     */
+    public void onSubscribeTerminated(int reason) {
+        Log.w(TAG, "onSubscribeTerminated: called in stub - override if interested or disable");
+    }
+
+    /**
+     * Called when a discovery (publish or subscribe) operation results in a
+     * match - i.e. when a peer is discovered. It is dummy method (empty
+     * implementation printing out a log message). Override to implement your
+     * custom response.
+     *
+     * @param peerId The ID of the peer matching our discovery operation.
+     * @param serviceSpecificInfo The service specific information (arbitrary
+     *            byte array) provided by the peer as part of its discovery
+     *            packet.
+     * @param serviceSpecificInfoLength The length of the service specific
+     *            information array.
+     * @param matchFilter The filter (Tx on advertiser and Rx on listener) which
+     *            resulted in this match.
+     * @param matchFilterLength The length of the match filter array.
+     */
+    public void onMatch(int peerId, byte[] serviceSpecificInfo,
+            int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
+        if (VDBG) Log.v(TAG, "onMatch: called in stub - override if interested");
+    }
+
+    /**
+     * Called when a message is transmitted successfully - i.e. when we know
+     * that it was received successfully (corresponding to an ACK being
+     * received). It is dummy method (empty implementation printing out a log
+     * message). Override to implement your custom response.
+     * <p>
+     * Note that either this callback or
+     * {@link WifiNanSessionListener#onMessageSendFail(int)} will be received -
+     * never both.
+     */
+    public void onMessageSendSuccess() {
+        if (VDBG) Log.v(TAG, "onMessageSendSuccess: called in stub - override if interested");
+    }
+
+    /**
+     * Called when a message transmission fails - i.e. when no ACK is received.
+     * The hardware will usually attempt to re-transmit several times - this
+     * event is received after all retries are exhausted. There is a possibility
+     * that message was received by the destination successfully but the ACK was
+     * lost. It is dummy method (empty implementation printing out a log
+     * message). Override to implement your custom response.
+     * <p>
+     * Note that either this callback or
+     * {@link WifiNanSessionListener#onMessageSendSuccess()} will be received -
+     * never both
+     *
+     * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
+     *            codes.
+     */
+    public void onMessageSendFail(int reason) {
+        if (VDBG) Log.v(TAG, "onMessageSendFail: called in stub - override if interested");
+    }
+
+    /**
+     * Called when a message is received from a discovery session peer. It is
+     * dummy method (empty implementation printing out a log message). Override
+     * to implement your custom response.
+     *
+     * @param peerId The ID of the peer sending the message.
+     * @param message A byte array containing the message.
+     * @param messageLength The length of the byte array containing the relevant
+     *            message bytes.
+     */
+    public void onMessageReceived(int peerId, byte[] message, int messageLength) {
+        if (VDBG) Log.v(TAG, "onMessageReceived: called in stub - override if interested");
+    }
+
+    /**
+     * {@hide}
+     */
+    public IWifiNanSessionListener callback = new IWifiNanSessionListener.Stub() {
+        @Override
+        public void onPublishFail(int reason) {
+            if (VDBG) Log.v(TAG, "onPublishFail: reason=" + reason);
+
+            Message msg = mHandler.obtainMessage(LISTEN_PUBLISH_FAIL);
+            msg.arg1 = reason;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onPublishTerminated(int reason) {
+            if (VDBG) Log.v(TAG, "onPublishResponse: reason=" + reason);
+
+            Message msg = mHandler.obtainMessage(LISTEN_PUBLISH_TERMINATED);
+            msg.arg1 = reason;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onSubscribeFail(int reason) {
+            if (VDBG) Log.v(TAG, "onSubscribeFail: reason=" + reason);
+
+            Message msg = mHandler.obtainMessage(LISTEN_SUBSCRIBE_FAIL);
+            msg.arg1 = reason;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onSubscribeTerminated(int reason) {
+            if (VDBG) Log.v(TAG, "onSubscribeTerminated: reason=" + reason);
+
+            Message msg = mHandler.obtainMessage(LISTEN_SUBSCRIBE_TERMINATED);
+            msg.arg1 = reason;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onMatch(int peerId, byte[] serviceSpecificInfo,
+                int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
+            if (VDBG) Log.v(TAG, "onMatch: peerId=" + peerId);
+
+            Bundle data = new Bundle();
+            data.putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId);
+            data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, serviceSpecificInfo);
+            data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2, matchFilter);
+
+            Message msg = mHandler.obtainMessage(LISTEN_MATCH);
+            msg.arg1 = serviceSpecificInfoLength;
+            msg.arg2 = matchFilterLength;
+            msg.setData(data);
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onMessageSendSuccess() {
+            if (VDBG) Log.v(TAG, "onMessageSendSuccess");
+
+            Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_SEND_SUCCESS);
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onMessageSendFail(int reason) {
+            if (VDBG) Log.v(TAG, "onMessageSendFail: reason=" + reason);
+
+            Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_SEND_FAIL);
+            msg.arg1 = reason;
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void onMessageReceived(int peerId, byte[] message, int messageLength) {
+            if (VDBG) {
+                Log.v(TAG, "onMessageReceived: peerId='" + peerId + "', messageLength="
+                        + messageLength);
+            }
+
+            Bundle data = new Bundle();
+            data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message);
+
+            Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_RECEIVED);
+            msg.arg1 = messageLength;
+            msg.arg2 = peerId;
+            msg.setData(data);
+            mHandler.sendMessage(msg);
+        }
+    };
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java b/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
new file mode 100644
index 0000000..7dfdd32
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nan;
+
+/**
+ * A representation of a NAN subscribe session. Created when
+ * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
+ * is executed. The object can be used to stop and re-start (re-configure) the
+ * subscribe session.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanSubscribeSession extends WifiNanSession {
+    /**
+     * {@hide}
+     */
+    public WifiNanSubscribeSession(WifiNanManager manager, int sessionId) {
+        super(manager, sessionId);
+    }
+
+    /**
+     * Restart/re-configure the subscribe session. Note that the
+     * {@link WifiNanSessionListener} is not replaced - the same listener used at
+     * creation is still used.
+     *
+     * @param subscribeData The data ({@link SubscribeData}) to subscribe.
+     * @param subscribeSettings The settings ({@link SubscribeSettings}) of the
+     *            subscribe session.
+     */
+    public void subscribe(SubscribeData subscribeData, SubscribeSettings subscribeSettings) {
+        mManager.subscribe(mSessionId, subscribeData, subscribeSettings);
+    }
+}