Merge "Remove DEBUG_JIT from Zygote flags."
diff --git a/Android.mk b/Android.mk
index f0c0117..71bba0f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -259,6 +259,7 @@
 	core/java/android/view/accessibility/IAccessibilityManager.aidl \
 	core/java/android/view/accessibility/IAccessibilityManagerClient.aidl \
 	core/java/android/view/IApplicationToken.aidl \
+	core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl \
 	core/java/android/view/IAssetAtlas.aidl \
 	core/java/android/view/IGraphicsStats.aidl \
 	core/java/android/view/IInputFilter.aidl \
diff --git a/api/current.txt b/api/current.txt
index 3e63cd7..de9abd0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -499,6 +499,7 @@
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
     field public static final int enabled = 16842766; // 0x101000e
+    field public static final int encryptionAware = 16844038; // 0x1010506
     field public static final int end = 16843996; // 0x10104dc
     field public static final int endColor = 16843166; // 0x101019e
     field public static final deprecated int endYear = 16843133; // 0x101017d
@@ -559,6 +560,7 @@
     field public static final int fontFamily = 16843692; // 0x10103ac
     field public static final int fontFeatureSettings = 16843959; // 0x10104b7
     field public static final int footerDividersEnabled = 16843311; // 0x101022f
+    field public static final int forceDeviceEncrypted = 16844037; // 0x1010505
     field public static final int foreground = 16843017; // 0x1010109
     field public static final int foregroundGravity = 16843264; // 0x1010200
     field public static final int foregroundTint = 16843885; // 0x101046d
@@ -931,6 +933,7 @@
     field public static final int port = 16842793; // 0x1010029
     field public static final int positiveButtonText = 16843253; // 0x10101f5
     field public static final int preferenceCategoryStyle = 16842892; // 0x101008c
+    field public static final int preferenceFragmentStyle = 16844039; // 0x1010507
     field public static final int preferenceInformationStyle = 16842893; // 0x101008d
     field public static final int preferenceLayoutChild = 16842900; // 0x1010094
     field public static final int preferenceScreenStyle = 16842891; // 0x101008b
@@ -1708,11 +1711,13 @@
     field public static final int icon = 16908294; // 0x1020006
     field public static final int icon1 = 16908295; // 0x1020007
     field public static final int icon2 = 16908296; // 0x1020008
+    field public static final int icon_frame = 16908350; // 0x102003e
     field public static final int input = 16908297; // 0x1020009
     field public static final int inputArea = 16908318; // 0x102001e
     field public static final int inputExtractEditText = 16908325; // 0x1020025
     field public static final int keyboardView = 16908326; // 0x1020026
     field public static final int list = 16908298; // 0x102000a
+    field public static final int list_container = 16908351; // 0x102003f
     field public static final int mask = 16908334; // 0x102002e
     field public static final int message = 16908299; // 0x102000b
     field public static final int navigationBarBackground = 16908336; // 0x1020030
@@ -1732,6 +1737,7 @@
     field public static final int stopSelectingText = 16908329; // 0x1020029
     field public static final int summary = 16908304; // 0x1020010
     field public static final int switchInputMethod = 16908324; // 0x1020024
+    field public static final int switch_widget = 16908352; // 0x1020040
     field public static final int tabcontent = 16908305; // 0x1020011
     field public static final int tabhost = 16908306; // 0x1020012
     field public static final int tabs = 16908307; // 0x1020013
@@ -5705,6 +5711,7 @@
     method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
     method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
     method public int getCurrentFailedPasswordAttempts();
+    method public java.lang.String getDeviceOwnerLockScreenInfo();
     method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
@@ -5730,6 +5737,7 @@
     method public int getStorageEncryptionStatus();
     method public android.app.admin.SystemUpdatePolicy getSystemUpdatePolicy();
     method public java.util.List<android.os.PersistableBundle> getTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName);
+    method public android.os.Bundle getUserRestrictions(android.content.ComponentName);
     method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
     method public boolean installCaCert(android.content.ComponentName, byte[]);
@@ -5741,6 +5749,7 @@
     method public boolean isLockTaskPermitted(java.lang.String);
     method public boolean isMasterVolumeMuted(android.content.ComponentName);
     method public boolean isProfileOwnerApp(java.lang.String);
+    method public boolean isProvisioningAllowed(java.lang.String);
     method public boolean isUninstallBlocked(android.content.ComponentName, java.lang.String);
     method public void lockNow();
     method public void removeActiveAdmin(android.content.ComponentName);
@@ -5755,6 +5764,7 @@
     method public void setCameraDisabled(android.content.ComponentName, boolean);
     method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
     method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+    method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
     method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
     method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
@@ -7738,6 +7748,7 @@
     method public final android.content.res.ColorStateList getColorStateList(int);
     method public abstract android.content.ContentResolver getContentResolver();
     method public abstract java.io.File getDatabasePath(java.lang.String);
+    method public abstract java.io.File getDeviceEncryptedFilesDir();
     method public abstract java.io.File getDir(java.lang.String, int);
     method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
@@ -7920,6 +7931,7 @@
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
+    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -9059,6 +9071,7 @@
     field public android.content.pm.ApplicationInfo applicationInfo;
     field public int descriptionRes;
     field public boolean enabled;
+    field public boolean encryptionAware;
     field public boolean exported;
     field public java.lang.String processName;
   }
@@ -9480,6 +9493,7 @@
     field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
     field public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
     field public static final int GET_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000
+    field public static final int GET_ENCRYPTION_UNAWARE_COMPONENTS = 262144; // 0x40000
     field public static final int GET_GIDS = 256; // 0x100
     field public static final int GET_INSTRUMENTATION = 16; // 0x10
     field public static final int GET_INTENT_FILTERS = 32; // 0x20
@@ -9906,6 +9920,7 @@
   public static class Resources.NotFoundException extends java.lang.RuntimeException {
     ctor public Resources.NotFoundException();
     ctor public Resources.NotFoundException(java.lang.String);
+    ctor public Resources.NotFoundException(java.lang.String, java.lang.Exception);
   }
 
   public final class Resources.Theme {
@@ -15505,6 +15520,7 @@
     field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
     field public static final deprecated int BUFFER_FLAG_SYNC_FRAME = 1; // 0x1
     field public static final int CONFIGURE_FLAG_ENCODE = 1; // 0x1
+    field public static final int CRYPTO_MODE_AES_CBC = 2; // 0x2
     field public static final int CRYPTO_MODE_AES_CTR = 1; // 0x1
     field public static final int CRYPTO_MODE_UNENCRYPTED = 0; // 0x0
     field public static final deprecated int INFO_OUTPUT_BUFFERS_CHANGED = -3; // 0xfffffffd
@@ -15556,6 +15572,7 @@
   public static final class MediaCodec.CryptoInfo {
     ctor public MediaCodec.CryptoInfo();
     method public void set(int, int[], int[], byte[], byte[], int);
+    method public void setPattern(android.media.MediaCodec.CryptoInfo.Pattern);
     field public byte[] iv;
     field public byte[] key;
     field public int mode;
@@ -15564,6 +15581,13 @@
     field public int numSubSamples;
   }
 
+  public static final class MediaCodec.CryptoInfo.Pattern {
+    ctor public MediaCodec.CryptoInfo.Pattern(int, int);
+    method public int getEncryptBlocks();
+    method public int getSkipBlocks();
+    method public void set(int, int);
+  }
+
   public static abstract interface MediaCodec.OnFrameRenderedListener {
     method public abstract void onFrameRendered(android.media.MediaCodec, long, long);
   }
@@ -17753,6 +17777,7 @@
 package android.media.tv {
 
   public final class TvContentRating {
+    method public final boolean contains(android.media.tv.TvContentRating);
     method public static android.media.tv.TvContentRating createRating(java.lang.String, java.lang.String, java.lang.String, java.lang.String...);
     method public java.lang.String flattenToString();
     method public java.lang.String getDomain();
@@ -31931,6 +31956,7 @@
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
+    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
diff --git a/api/system-current.txt b/api/system-current.txt
index bd674ef..65ecdc1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -591,6 +591,7 @@
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
     field public static final int enabled = 16842766; // 0x101000e
+    field public static final int encryptionAware = 16844038; // 0x1010506
     field public static final int end = 16843996; // 0x10104dc
     field public static final int endColor = 16843166; // 0x101019e
     field public static final deprecated int endYear = 16843133; // 0x101017d
@@ -651,6 +652,7 @@
     field public static final int fontFamily = 16843692; // 0x10103ac
     field public static final int fontFeatureSettings = 16843959; // 0x10104b7
     field public static final int footerDividersEnabled = 16843311; // 0x101022f
+    field public static final int forceDeviceEncrypted = 16844037; // 0x1010505
     field public static final int foreground = 16843017; // 0x1010109
     field public static final int foregroundGravity = 16843264; // 0x1010200
     field public static final int foregroundTint = 16843885; // 0x101046d
@@ -1023,6 +1025,7 @@
     field public static final int port = 16842793; // 0x1010029
     field public static final int positiveButtonText = 16843253; // 0x10101f5
     field public static final int preferenceCategoryStyle = 16842892; // 0x101008c
+    field public static final int preferenceFragmentStyle = 16844039; // 0x1010507
     field public static final int preferenceInformationStyle = 16842893; // 0x101008d
     field public static final int preferenceLayoutChild = 16842900; // 0x1010094
     field public static final int preferenceScreenStyle = 16842891; // 0x101008b
@@ -1804,11 +1807,13 @@
     field public static final int icon = 16908294; // 0x1020006
     field public static final int icon1 = 16908295; // 0x1020007
     field public static final int icon2 = 16908296; // 0x1020008
+    field public static final int icon_frame = 16908350; // 0x102003e
     field public static final int input = 16908297; // 0x1020009
     field public static final int inputArea = 16908318; // 0x102001e
     field public static final int inputExtractEditText = 16908325; // 0x1020025
     field public static final int keyboardView = 16908326; // 0x1020026
     field public static final int list = 16908298; // 0x102000a
+    field public static final int list_container = 16908351; // 0x102003f
     field public static final int mask = 16908334; // 0x102002e
     field public static final int message = 16908299; // 0x102000b
     field public static final int navigationBarBackground = 16908336; // 0x1020030
@@ -1828,6 +1833,7 @@
     field public static final int stopSelectingText = 16908329; // 0x1020029
     field public static final int summary = 16908304; // 0x1020010
     field public static final int switchInputMethod = 16908324; // 0x1020024
+    field public static final int switch_widget = 16908352; // 0x1020040
     field public static final int tabcontent = 16908305; // 0x1020011
     field public static final int tabhost = 16908306; // 0x1020012
     field public static final int tabs = 16908307; // 0x1020013
@@ -5831,6 +5837,7 @@
     method public deprecated java.lang.String getDeviceInitializerApp();
     method public deprecated android.content.ComponentName getDeviceInitializerComponent();
     method public java.lang.String getDeviceOwner();
+    method public java.lang.String getDeviceOwnerLockScreenInfo();
     method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
@@ -5860,6 +5867,7 @@
     method public int getStorageEncryptionStatus();
     method public android.app.admin.SystemUpdatePolicy getSystemUpdatePolicy();
     method public java.util.List<android.os.PersistableBundle> getTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName);
+    method public android.os.Bundle getUserRestrictions(android.content.ComponentName);
     method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
     method public boolean installCaCert(android.content.ComponentName, byte[]);
@@ -5871,6 +5879,7 @@
     method public boolean isLockTaskPermitted(java.lang.String);
     method public boolean isMasterVolumeMuted(android.content.ComponentName);
     method public boolean isProfileOwnerApp(java.lang.String);
+    method public boolean isProvisioningAllowed(java.lang.String);
     method public boolean isUninstallBlocked(android.content.ComponentName, java.lang.String);
     method public void lockNow();
     method public void notifyPendingSystemUpdate(long);
@@ -5887,6 +5896,7 @@
     method public void setCameraDisabled(android.content.ComponentName, boolean);
     method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
     method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+    method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
     method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
     method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
@@ -7979,7 +7989,9 @@
     method public final int getColor(int);
     method public final android.content.res.ColorStateList getColorStateList(int);
     method public abstract android.content.ContentResolver getContentResolver();
+    method public abstract java.io.File getCredentialEncryptedFilesDir();
     method public abstract java.io.File getDatabasePath(java.lang.String);
+    method public abstract java.io.File getDeviceEncryptedFilesDir();
     method public abstract java.io.File getDir(java.lang.String, int);
     method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
@@ -8169,7 +8181,9 @@
     method public java.lang.ClassLoader getClassLoader();
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
+    method public java.io.File getCredentialEncryptedFilesDir();
     method public java.io.File getDatabasePath(java.lang.String);
+    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -9317,6 +9331,7 @@
     field public android.content.pm.ApplicationInfo applicationInfo;
     field public int descriptionRes;
     field public boolean enabled;
+    field public boolean encryptionAware;
     field public boolean exported;
     field public java.lang.String processName;
   }
@@ -9775,6 +9790,7 @@
     field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
     field public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
     field public static final int GET_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000
+    field public static final int GET_ENCRYPTION_UNAWARE_COMPONENTS = 262144; // 0x40000
     field public static final int GET_GIDS = 256; // 0x100
     field public static final int GET_INSTRUMENTATION = 16; // 0x10
     field public static final int GET_INTENT_FILTERS = 32; // 0x20
@@ -10245,6 +10261,7 @@
   public static class Resources.NotFoundException extends java.lang.RuntimeException {
     ctor public Resources.NotFoundException();
     ctor public Resources.NotFoundException(java.lang.String);
+    ctor public Resources.NotFoundException(java.lang.String, java.lang.Exception);
   }
 
   public final class Resources.Theme {
@@ -14483,7 +14500,7 @@
     field public static final int POWER_STATUS_TRANSIENT_TO_ON = 2; // 0x2
     field public static final int POWER_STATUS_TRANSIENT_TO_STANDBY = 3; // 0x3
     field public static final int POWER_STATUS_UNKNOWN = -1; // 0xffffffff
-    field public static final int RESULT_ALREADY_IN_PROGRESS = 4; // 0x4
+    field public static final deprecated int RESULT_ALREADY_IN_PROGRESS = 4; // 0x4
     field public static final int RESULT_COMMUNICATION_FAILED = 7; // 0x7
     field public static final int RESULT_EXCEPTION = 5; // 0x5
     field public static final int RESULT_INCORRECT_MODE = 6; // 0x6
@@ -14919,6 +14936,7 @@
 
   public static class RadioManager.FmBandConfig extends android.hardware.radio.RadioManager.BandConfig {
     method public boolean getAf();
+    method public boolean getEa();
     method public boolean getRds();
     method public boolean getStereo();
     method public boolean getTa();
@@ -14930,6 +14948,7 @@
     ctor public RadioManager.FmBandConfig.Builder(android.hardware.radio.RadioManager.FmBandConfig);
     method public android.hardware.radio.RadioManager.FmBandConfig build();
     method public android.hardware.radio.RadioManager.FmBandConfig.Builder setAf(boolean);
+    method public android.hardware.radio.RadioManager.FmBandConfig.Builder setEa(boolean);
     method public android.hardware.radio.RadioManager.FmBandConfig.Builder setRds(boolean);
     method public android.hardware.radio.RadioManager.FmBandConfig.Builder setStereo(boolean);
     method public android.hardware.radio.RadioManager.FmBandConfig.Builder setTa(boolean);
@@ -14937,6 +14956,7 @@
 
   public static class RadioManager.FmBandDescriptor extends android.hardware.radio.RadioManager.BandDescriptor {
     method public boolean isAfSupported();
+    method public boolean isEaSupported();
     method public boolean isRdsSupported();
     method public boolean isStereoSupported();
     method public boolean isTaSupported();
@@ -14976,6 +14996,7 @@
     method public boolean containsKey(java.lang.String);
     method public int describeContents();
     method public android.graphics.Bitmap getBitmap(java.lang.String);
+    method public android.hardware.radio.RadioMetadata.Clock getClock(java.lang.String);
     method public int getInt(java.lang.String);
     method public java.lang.String getString(java.lang.String);
     method public java.util.Set<java.lang.String> keySet();
@@ -14985,6 +15006,7 @@
     field public static final java.lang.String METADATA_KEY_ALBUM = "android.hardware.radio.metadata.ALBUM";
     field public static final java.lang.String METADATA_KEY_ART = "android.hardware.radio.metadata.ART";
     field public static final java.lang.String METADATA_KEY_ARTIST = "android.hardware.radio.metadata.ARTIST";
+    field public static final java.lang.String METADATA_KEY_CLOCK = "android.hardware.radio.metadata.CLOCK";
     field public static final java.lang.String METADATA_KEY_GENRE = "android.hardware.radio.metadata.GENRE";
     field public static final java.lang.String METADATA_KEY_ICON = "android.hardware.radio.metadata.ICON";
     field public static final java.lang.String METADATA_KEY_RBDS_PTY = "android.hardware.radio.metadata.RBDS_PTY";
@@ -15000,10 +15022,20 @@
     ctor public RadioMetadata.Builder(android.hardware.radio.RadioMetadata);
     method public android.hardware.radio.RadioMetadata build();
     method public android.hardware.radio.RadioMetadata.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+    method public android.hardware.radio.RadioMetadata.Builder putClock(java.lang.String, long, int);
     method public android.hardware.radio.RadioMetadata.Builder putInt(java.lang.String, int);
     method public android.hardware.radio.RadioMetadata.Builder putString(java.lang.String, java.lang.String);
   }
 
+  public static final class RadioMetadata.Clock implements android.os.Parcelable {
+    ctor public RadioMetadata.Clock(long, int);
+    method public int describeContents();
+    method public int getTimezoneOffsetMinutes();
+    method public long getUtcEpochSeconds();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.radio.RadioMetadata.Clock> CREATOR;
+  }
+
   public abstract class RadioTuner {
     ctor public RadioTuner();
     method public abstract int cancel();
@@ -15032,6 +15064,7 @@
     method public void onAntennaState(boolean);
     method public void onConfigurationChanged(android.hardware.radio.RadioManager.BandConfig);
     method public void onControlChanged(boolean);
+    method public void onEmergencyAnnouncement(boolean);
     method public void onError(int);
     method public void onMetadataChanged(android.hardware.radio.RadioMetadata);
     method public void onProgramInfoChanged(android.hardware.radio.RadioManager.ProgramInfo);
@@ -16772,6 +16805,7 @@
     field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
     field public static final deprecated int BUFFER_FLAG_SYNC_FRAME = 1; // 0x1
     field public static final int CONFIGURE_FLAG_ENCODE = 1; // 0x1
+    field public static final int CRYPTO_MODE_AES_CBC = 2; // 0x2
     field public static final int CRYPTO_MODE_AES_CTR = 1; // 0x1
     field public static final int CRYPTO_MODE_UNENCRYPTED = 0; // 0x0
     field public static final deprecated int INFO_OUTPUT_BUFFERS_CHANGED = -3; // 0xfffffffd
@@ -16823,6 +16857,7 @@
   public static final class MediaCodec.CryptoInfo {
     ctor public MediaCodec.CryptoInfo();
     method public void set(int, int[], int[], byte[], byte[], int);
+    method public void setPattern(android.media.MediaCodec.CryptoInfo.Pattern);
     field public byte[] iv;
     field public byte[] key;
     field public int mode;
@@ -16831,6 +16866,13 @@
     field public int numSubSamples;
   }
 
+  public static final class MediaCodec.CryptoInfo.Pattern {
+    ctor public MediaCodec.CryptoInfo.Pattern(int, int);
+    method public int getEncryptBlocks();
+    method public int getSkipBlocks();
+    method public void set(int, int);
+  }
+
   public static abstract interface MediaCodec.OnFrameRenderedListener {
     method public abstract void onFrameRendered(android.media.MediaCodec, long, long);
   }
@@ -20273,6 +20315,7 @@
     method public static void incrementOperationCount(int, int);
     method public static void setThreadStatsTag(int);
     method public static void setThreadStatsTagBackup();
+    method public static void setThreadStatsTagRestore();
     method public static void setThreadStatsUid(int);
     method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
     method public static void untagSocket(java.net.Socket) throws java.net.SocketException;
@@ -34220,7 +34263,9 @@
     method public java.lang.ClassLoader getClassLoader();
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
+    method public java.io.File getCredentialEncryptedFilesDir();
     method public java.io.File getDatabasePath(java.lang.String);
+    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 7f33cb5..62e0919a 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -55,6 +55,7 @@
 import android.os.RemoteException;
 import android.os.SELinux;
 import android.os.ServiceManager;
+import android.os.ShellCommand;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -72,6 +73,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
+import java.io.PrintWriter;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -117,7 +119,8 @@
 
     @Override
     public void onShowUsage(PrintStream out) {
-        out.println(
+        PrintWriter pw = new PrintWriter(out);
+        pw.println(
                 "usage: am [subcommand] [options]\n" +
                 "usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
                 "               [--sampling INTERVAL] [-R COUNT] [-S]\n" +
@@ -337,52 +340,10 @@
                 "am send-trim-memory: send a memory trim event to a <PROCESS>.\n" +
                 "\n" +
                 "am get-current-user: returns id of the current foreground user.\n" +
-                "\n" +
-                "<INTENT> specifications include these flags and arguments:\n" +
-                "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
-                "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
-                "    [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]\n" +
-                "    [--esn <EXTRA_KEY> ...]\n" +
-                "    [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]\n" +
-                "    [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" +
-                "    [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" +
-                "    [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]\n" +
-                "    [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" +
-                "    [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]\n" +
-                "    [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
-                "        (mutiple extras passed as Integer[])\n" +
-                "    [--eial <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
-                "        (mutiple extras passed as List<Integer>)\n" +
-                "    [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
-                "        (mutiple extras passed as Long[])\n" +
-                "    [--elal <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
-                "        (mutiple extras passed as List<Long>)\n" +
-                "    [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
-                "        (mutiple extras passed as Float[])\n" +
-                "    [--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
-                "        (mutiple extras passed as List<Float>)\n" +
-                "    [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" +
-                "        (mutiple extras passed as String[]; to embed a comma into a string,\n" +
-                "         escape it using \"\\,\")\n" +
-                "    [--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" +
-                "        (mutiple extras passed as List<String>; to embed a comma into a string,\n" +
-                "         escape it using \"\\,\")\n" +
-                "    [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
-                "    [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]\n" +
-                "    [--debug-log-resolution] [--exclude-stopped-packages]\n" +
-                "    [--include-stopped-packages]\n" +
-                "    [--activity-brought-to-front] [--activity-clear-top]\n" +
-                "    [--activity-clear-when-task-reset] [--activity-exclude-from-recents]\n" +
-                "    [--activity-launched-from-history] [--activity-multiple-task]\n" +
-                "    [--activity-no-animation] [--activity-no-history]\n" +
-                "    [--activity-no-user-action] [--activity-previous-is-top]\n" +
-                "    [--activity-reorder-to-front] [--activity-reset-task-if-needed]\n" +
-                "    [--activity-single-top] [--activity-clear-task]\n" +
-                "    [--activity-task-on-home]\n" +
-                "    [--receiver-registered-only] [--receiver-replace-pending]\n" +
-                "    [--selector]\n" +
-                "    [<URI> | <PACKAGE> | <COMPONENT>]\n"
-                );
+                "\n"
+        );
+        Intent.printIntentArgsHelp(pw, "");
+        pw.flush();
     }
 
     @Override
@@ -486,10 +447,6 @@
     }
 
     private Intent makeIntent(int defUser) throws URISyntaxException {
-        Intent intent = new Intent();
-        Intent baseIntent = intent;
-        boolean hasIntentInfo = false;
-
         mStartFlags = 0;
         mWaitOption = false;
         mStopOption = false;
@@ -498,316 +455,38 @@
         mSamplingInterval = 0;
         mAutoStop = false;
         mUserId = defUser;
-        Uri data = null;
-        String type = null;
 
-        String opt;
-        while ((opt=nextOption()) != null) {
-            if (opt.equals("-a")) {
-                intent.setAction(nextArgRequired());
-                if (intent == baseIntent) {
-                    hasIntentInfo = true;
-                }
-            } else if (opt.equals("-d")) {
-                data = Uri.parse(nextArgRequired());
-                if (intent == baseIntent) {
-                    hasIntentInfo = true;
-                }
-            } else if (opt.equals("-t")) {
-                type = nextArgRequired();
-                if (intent == baseIntent) {
-                    hasIntentInfo = true;
-                }
-            } else if (opt.equals("-c")) {
-                intent.addCategory(nextArgRequired());
-                if (intent == baseIntent) {
-                    hasIntentInfo = true;
-                }
-            } else if (opt.equals("-e") || opt.equals("--es")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                intent.putExtra(key, value);
-            } else if (opt.equals("--esn")) {
-                String key = nextArgRequired();
-                intent.putExtra(key, (String) null);
-            } else if (opt.equals("--ei")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                intent.putExtra(key, Integer.decode(value));
-            } else if (opt.equals("--eu")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                intent.putExtra(key, Uri.parse(value));
-            } else if (opt.equals("--ecn")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                ComponentName cn = ComponentName.unflattenFromString(value);
-                if (cn == null) throw new IllegalArgumentException("Bad component name: " + value);
-                intent.putExtra(key, cn);
-            } else if (opt.equals("--eia")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                String[] strings = value.split(",");
-                int[] list = new int[strings.length];
-                for (int i = 0; i < strings.length; i++) {
-                    list[i] = Integer.decode(strings[i]);
-                }
-                intent.putExtra(key, list);
-            } else if (opt.equals("--eial")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                String[] strings = value.split(",");
-                ArrayList<Integer> list = new ArrayList<>(strings.length);
-                for (int i = 0; i < strings.length; i++) {
-                    list.add(Integer.decode(strings[i]));
-                }
-                intent.putExtra(key, list);
-            } else if (opt.equals("--el")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                intent.putExtra(key, Long.valueOf(value));
-            } else if (opt.equals("--ela")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                String[] strings = value.split(",");
-                long[] list = new long[strings.length];
-                for (int i = 0; i < strings.length; i++) {
-                    list[i] = Long.valueOf(strings[i]);
-                }
-                intent.putExtra(key, list);
-                hasIntentInfo = true;
-            } else if (opt.equals("--elal")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                String[] strings = value.split(",");
-                ArrayList<Long> list = new ArrayList<>(strings.length);
-                for (int i = 0; i < strings.length; i++) {
-                    list.add(Long.valueOf(strings[i]));
-                }
-                intent.putExtra(key, list);
-                hasIntentInfo = true;
-            } else if (opt.equals("--ef")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                intent.putExtra(key, Float.valueOf(value));
-                hasIntentInfo = true;
-            } else if (opt.equals("--efa")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                String[] strings = value.split(",");
-                float[] list = new float[strings.length];
-                for (int i = 0; i < strings.length; i++) {
-                    list[i] = Float.valueOf(strings[i]);
-                }
-                intent.putExtra(key, list);
-                hasIntentInfo = true;
-            } else if (opt.equals("--efal")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                String[] strings = value.split(",");
-                ArrayList<Float> list = new ArrayList<>(strings.length);
-                for (int i = 0; i < strings.length; i++) {
-                    list.add(Float.valueOf(strings[i]));
-                }
-                intent.putExtra(key, list);
-                hasIntentInfo = true;
-            } else if (opt.equals("--esa")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                // Split on commas unless they are preceeded by an escape.
-                // The escape character must be escaped for the string and
-                // again for the regex, thus four escape characters become one.
-                String[] strings = value.split("(?<!\\\\),");
-                intent.putExtra(key, strings);
-                hasIntentInfo = true;
-            } else if (opt.equals("--esal")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired();
-                // Split on commas unless they are preceeded by an escape.
-                // The escape character must be escaped for the string and
-                // again for the regex, thus four escape characters become one.
-                String[] strings = value.split("(?<!\\\\),");
-                ArrayList<String> list = new ArrayList<>(strings.length);
-                for (int i = 0; i < strings.length; i++) {
-                    list.add(strings[i]);
-                }
-                intent.putExtra(key, list);
-                hasIntentInfo = true;
-            } else if (opt.equals("--ez")) {
-                String key = nextArgRequired();
-                String value = nextArgRequired().toLowerCase();
-                // Boolean.valueOf() results in false for anything that is not "true", which is
-                // error-prone in shell commands
-                boolean arg;
-                if ("true".equals(value) || "t".equals(value)) {
-                    arg = true;
-                } else if ("false".equals(value) || "f".equals(value)) {
-                    arg = false;
+        return Intent.parseCommandArgs(mArgs, new Intent.CommandOptionHandler() {
+            @Override
+            public boolean handleOption(String opt, ShellCommand cmd) {
+                if (opt.equals("-D")) {
+                    mStartFlags |= ActivityManager.START_FLAG_DEBUG;
+                } else if (opt.equals("-W")) {
+                    mWaitOption = true;
+                } else if (opt.equals("-P")) {
+                    mProfileFile = nextArgRequired();
+                    mAutoStop = true;
+                } else if (opt.equals("--start-profiler")) {
+                    mProfileFile = nextArgRequired();
+                    mAutoStop = false;
+                } else if (opt.equals("--sampling")) {
+                    mSamplingInterval = Integer.parseInt(nextArgRequired());
+                } else if (opt.equals("-R")) {
+                    mRepeat = Integer.parseInt(nextArgRequired());
+                } else if (opt.equals("-S")) {
+                    mStopOption = true;
+                } else if (opt.equals("--track-allocation")) {
+                    mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
+                } else if (opt.equals("--user")) {
+                    mUserId = parseUserArg(nextArgRequired());
+                } else if (opt.equals("--receiver-permission")) {
+                    mReceiverPermission = nextArgRequired();
                 } else {
-                    try {
-                        arg = Integer.decode(value) != 0;
-                    } catch (NumberFormatException ex) {
-                        throw new IllegalArgumentException("Invalid boolean value: " + value);
-                    }
+                    return false;
                 }
-
-                intent.putExtra(key, arg);
-            } else if (opt.equals("-n")) {
-                String str = nextArgRequired();
-                ComponentName cn = ComponentName.unflattenFromString(str);
-                if (cn == null) throw new IllegalArgumentException("Bad component name: " + str);
-                intent.setComponent(cn);
-                if (intent == baseIntent) {
-                    hasIntentInfo = true;
-                }
-            } else if (opt.equals("-p")) {
-                String str = nextArgRequired();
-                intent.setPackage(str);
-                if (intent == baseIntent) {
-                    hasIntentInfo = true;
-                }
-            } else if (opt.equals("-f")) {
-                String str = nextArgRequired();
-                intent.setFlags(Integer.decode(str).intValue());
-            } else if (opt.equals("--grant-read-uri-permission")) {
-                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-            } else if (opt.equals("--grant-write-uri-permission")) {
-                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-            } else if (opt.equals("--grant-persistable-uri-permission")) {
-                intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
-            } else if (opt.equals("--grant-prefix-uri-permission")) {
-                intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
-            } else if (opt.equals("--exclude-stopped-packages")) {
-                intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
-            } else if (opt.equals("--include-stopped-packages")) {
-                intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
-            } else if (opt.equals("--debug-log-resolution")) {
-                intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
-            } else if (opt.equals("--activity-brought-to-front")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
-            } else if (opt.equals("--activity-clear-top")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            } else if (opt.equals("--activity-clear-when-task-reset")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-            } else if (opt.equals("--activity-exclude-from-recents")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            } else if (opt.equals("--activity-launched-from-history")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
-            } else if (opt.equals("--activity-multiple-task")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-            } else if (opt.equals("--activity-no-animation")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
-            } else if (opt.equals("--activity-no-history")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
-            } else if (opt.equals("--activity-no-user-action")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
-            } else if (opt.equals("--activity-previous-is-top")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
-            } else if (opt.equals("--activity-reorder-to-front")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
-            } else if (opt.equals("--activity-reset-task-if-needed")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-            } else if (opt.equals("--activity-single-top")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-            } else if (opt.equals("--activity-clear-task")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            } else if (opt.equals("--activity-task-on-home")) {
-                intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
-            } else if (opt.equals("--receiver-registered-only")) {
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            } else if (opt.equals("--receiver-replace-pending")) {
-                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-            } else if (opt.equals("--selector")) {
-                intent.setDataAndType(data, type);
-                intent = new Intent();
-            } else if (opt.equals("-D")) {
-                mStartFlags |= ActivityManager.START_FLAG_DEBUG;
-            } else if (opt.equals("-W")) {
-                mWaitOption = true;
-            } else if (opt.equals("-P")) {
-                mProfileFile = nextArgRequired();
-                mAutoStop = true;
-            } else if (opt.equals("--start-profiler")) {
-                mProfileFile = nextArgRequired();
-                mAutoStop = false;
-            } else if (opt.equals("--sampling")) {
-                mSamplingInterval = Integer.parseInt(nextArgRequired());
-            } else if (opt.equals("-R")) {
-                mRepeat = Integer.parseInt(nextArgRequired());
-            } else if (opt.equals("-S")) {
-                mStopOption = true;
-            } else if (opt.equals("--track-allocation")) {
-                mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
-            } else if (opt.equals("--user")) {
-                mUserId = parseUserArg(nextArgRequired());
-            } else if (opt.equals("--receiver-permission")) {
-                mReceiverPermission = nextArgRequired();
-            } else {
-                throw new IllegalArgumentException("Unknown option: " + opt);
+                return true;
             }
-        }
-        intent.setDataAndType(data, type);
-
-        final boolean hasSelector = intent != baseIntent;
-        if (hasSelector) {
-            // A selector was specified; fix up.
-            baseIntent.setSelector(intent);
-            intent = baseIntent;
-        }
-
-        String arg = nextArg();
-        baseIntent = null;
-        if (arg == null) {
-            if (hasSelector) {
-                // If a selector has been specified, and no arguments
-                // have been supplied for the main Intent, then we can
-                // assume it is ACTION_MAIN CATEGORY_LAUNCHER; we don't
-                // need to have a component name specified yet, the
-                // selector will take care of that.
-                baseIntent = new Intent(Intent.ACTION_MAIN);
-                baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-            }
-        } else if (arg.indexOf(':') >= 0) {
-            // The argument is a URI.  Fully parse it, and use that result
-            // to fill in any data not specified so far.
-            baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME
-                    | Intent.URI_ANDROID_APP_SCHEME | Intent.URI_ALLOW_UNSAFE);
-        } else if (arg.indexOf('/') >= 0) {
-            // The argument is a component name.  Build an Intent to launch
-            // it.
-            baseIntent = new Intent(Intent.ACTION_MAIN);
-            baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-            baseIntent.setComponent(ComponentName.unflattenFromString(arg));
-        } else {
-            // Assume the argument is a package name.
-            baseIntent = new Intent(Intent.ACTION_MAIN);
-            baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-            baseIntent.setPackage(arg);
-        }
-        if (baseIntent != null) {
-            Bundle extras = intent.getExtras();
-            intent.replaceExtras((Bundle)null);
-            Bundle uriExtras = baseIntent.getExtras();
-            baseIntent.replaceExtras((Bundle)null);
-            if (intent.getAction() != null && baseIntent.getCategories() != null) {
-                HashSet<String> cats = new HashSet<String>(baseIntent.getCategories());
-                for (String c : cats) {
-                    baseIntent.removeCategory(c);
-                }
-            }
-            intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_SELECTOR);
-            if (extras == null) {
-                extras = uriExtras;
-            } else if (uriExtras != null) {
-                uriExtras.putAll(extras);
-                extras = uriExtras;
-            }
-            intent.replaceExtras(extras);
-            hasIntentInfo = true;
-        }
-
-        if (!hasIntentInfo) throw new IllegalArgumentException("No intent supplied");
-        return intent;
+        });
     }
 
     private void runStartService() throws Exception {
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
index 6b2f460..c13d318 100644
--- a/cmds/idmap/create.cpp
+++ b/cmds/idmap/create.cpp
@@ -1,6 +1,6 @@
 #include "idmap.h"
 
-#include <UniquePtr.h>
+#include <memory>
 #include <androidfw/AssetManager.h>
 #include <androidfw/ResourceTypes.h>
 #include <androidfw/ZipFileRO.h>
@@ -15,7 +15,7 @@
 namespace {
     int get_zip_entry_crc(const char *zip_path, const char *entry_name, uint32_t *crc)
     {
-        UniquePtr<ZipFileRO> zip(ZipFileRO::open(zip_path));
+        std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(zip_path));
         if (zip.get() == NULL) {
             return -1;
         }
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index f1b2f9e..6d30f0d 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -4,7 +4,7 @@
 
 #include "idmap.h"
 
-#include <UniquePtr.h>
+#include <memory>
 #include <androidfw/ResourceTypes.h>
 #include <androidfw/StreamingZipInflater.h>
 #include <androidfw/ZipFileRO.h>
@@ -120,7 +120,7 @@
 
     int parse_apk(const char *path, const char *target_package_name)
     {
-        UniquePtr<ZipFileRO> zip(ZipFileRO::open(path));
+        std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(path));
         if (zip.get() == NULL) {
             ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path);
             return -1;
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index ab781bb..659dc73 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -42,7 +42,6 @@
 import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
-import android.content.pm.VerificationParams;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -60,20 +59,18 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 
-import libcore.io.IoUtils;
-
 import com.android.internal.content.PackageHelper;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.SizedInputStream;
 
+import libcore.io.IoUtils;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
 
@@ -106,7 +103,7 @@
         System.exit(exitCode);
     }
 
-    public int run(String[] args) throws IOException, RemoteException {
+    public int run(String[] args) throws RemoteException {
         boolean validCommand = false;
         if (args.length < 1) {
             return showUsage();
@@ -142,19 +139,19 @@
         }
 
         if ("install-create".equals(op)) {
-            return runInstallCreate();
+            return runInstallSession();
         }
 
         if ("install-write".equals(op)) {
-            return runInstallWrite();
+            return runInstallSession();
         }
 
         if ("install-commit".equals(op)) {
-            return runInstallCommit();
+            return runInstallSession();
         }
 
         if ("install-abandon".equals(op) || "install-destroy".equals(op)) {
-            return runInstallAbandon();
+            return runInstallSession();
         }
 
         if ("set-installer".equals(op)) {
@@ -299,6 +296,210 @@
         return -1;
     }
 
+    private static class LocalIntentReceiver {
+        private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
+
+        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
+            @Override
+            public int send(int code, Intent intent, String resolvedType,
+                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
+                try {
+                    mResult.offer(intent, 5, TimeUnit.SECONDS);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+                return 0;
+            }
+        };
+
+        public IntentSender getIntentSender() {
+            return new IntentSender((IIntentSender) mLocalSender);
+        }
+
+        public Intent getResult() {
+            try {
+                return mResult.take();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private int translateUserId(int userId, String logContext) {
+        return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, logContext, "pm command");
+    }
+
+    private static String checkAbiArgument(String abi) {
+        if (TextUtils.isEmpty(abi)) {
+            throw new IllegalArgumentException("Missing ABI argument");
+        }
+        if ("-".equals(abi)) {
+            return abi;
+        }
+        final String[] supportedAbis = Build.SUPPORTED_ABIS;
+        for (String supportedAbi : supportedAbis) {
+            if (supportedAbi.equals(abi)) {
+                return abi;
+            }
+        }
+        throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
+    }
+
+    private void writeSessionFile(int sessionId, String path, long sizeBytes) throws RemoteException {
+        final SessionInfo info = mInstaller.getSessionInfo(sessionId);
+
+        PackageInstaller.Session session = null;
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+
+            if (path == null) {
+                in = new SizedInputStream(System.in, sizeBytes);
+            } else {
+                in = new FileInputStream(path);
+            }
+            out = session.openWrite("base.apk", 0, sizeBytes);
+
+            int total = 0;
+            byte[] buffer = new byte[65536];
+            int c;
+            while ((c = in.read(buffer)) != -1) {
+                total += c;
+                out.write(buffer, 0, c);
+
+                if (info.sizeBytes > 0) {
+                    final float fraction = ((float) c / (float) info.sizeBytes);
+                    session.addProgress(fraction);
+                }
+            }
+            session.fsync(out);
+        } catch (IOException ignore) {
+        } finally {
+            IoUtils.closeQuietly(out);
+            IoUtils.closeQuietly(in);
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    private int commitSessionFile(int sessionId) throws RemoteException {
+        PackageInstaller.Session session = null;
+        try {
+            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+
+            final LocalIntentReceiver receiver = new LocalIntentReceiver();
+            session.commit(receiver.getIntentSender());
+
+            final Intent result = receiver.getResult();
+            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                    PackageInstaller.STATUS_FAILURE);
+            if (status == PackageInstaller.STATUS_SUCCESS) {
+                System.out.println("Success");
+            } else {
+                System.err.println("Failure ["
+                        + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+            }
+            return status;
+        } finally {
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    /*
+     * Keep this around to support existing users of the "pm install" command that may not be
+     * able to be updated [or, at least informed the API has changed] such as ddmlib.
+     *
+     * Moving the implementation of "pm install" to "cmd package install" changes the executing
+     * context. Instead of being a stand alone process, "cmd package install" runs in the
+     * system_server process. Due to SELinux rules, system_server cannot access many directories;
+     * one of which being the package install staging directory [/data/local/tmp].
+     *
+     * The use of "adb install" or "cmd package install" over "pm install" is highly encouraged.
+     */
+    private int runInstall() throws RemoteException {
+        int userId = UserHandle.USER_ALL;
+        String installerPackageName = null;
+
+        final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
+
+        String opt;
+        while ((opt = nextOption()) != null) {
+            if (opt.equals("-l")) {
+                params.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+            } else if (opt.equals("-r")) {
+                params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
+            } else if (opt.equals("-i")) {
+                installerPackageName = nextArg();
+                if (installerPackageName == null) {
+                    throw new IllegalArgumentException("Missing installer package");
+                }
+            } else if (opt.equals("-t")) {
+                params.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
+            } else if (opt.equals("-s")) {
+                params.installFlags |= PackageManager.INSTALL_EXTERNAL;
+            } else if (opt.equals("-f")) {
+                params.installFlags |= PackageManager.INSTALL_INTERNAL;
+            } else if (opt.equals("-d")) {
+                params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+            } else if (opt.equals("-g")) {
+                params.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
+            } else if (opt.equals("--originating-uri")) {
+                params.originatingUri = Uri.parse(nextOptionData());
+            } else if (opt.equals("--referrer")) {
+                params.referrerUri = Uri.parse(nextOptionData());
+            } else if (opt.equals("-p")) {
+                params.mode = SessionParams.MODE_INHERIT_EXISTING;
+                params.appPackageName = nextOptionData();
+                if (params.appPackageName == null) {
+                    throw new IllegalArgumentException("Missing inherit package name");
+                }
+            } else if (opt.equals("-S")) {
+                params.setSize(Long.parseLong(nextOptionData()));
+            } else if (opt.equals("--abi")) {
+                params.abiOverride = checkAbiArgument(nextOptionData());
+            } else if (opt.equals("--user")) {
+                userId = Integer.parseInt(nextOptionData());
+            } else if (opt.equals("--install-location")) {
+                params.installLocation = Integer.parseInt(nextOptionData());
+            } else if (opt.equals("--force-uuid")) {
+                params.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
+                params.volumeUuid = nextOptionData();
+                if ("internal".equals(params.volumeUuid)) {
+                    params.volumeUuid = null;
+                }
+            } else {
+                throw new IllegalArgumentException("Unknown option " + opt);
+            }
+        }
+
+        userId = translateUserId(userId, "runInstallCreate");
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_SYSTEM;
+            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
+        }
+
+        long sizeBytes = params.sizeBytes;
+        String path = nextArg();
+        if ("-".equals(path)) {
+            path = null;
+        } else if (path != null) {
+            final File file = new File(path);
+            if (file.isFile()) {
+                sizeBytes = file.length();
+            }
+        }
+
+        final int sessionId = mInstaller.createSession(params, installerPackageName, userId);
+
+        writeSessionFile(sessionId, path, sizeBytes);
+        return commitSessionFile(sessionId);
+    }
+
+    private int runInstallSession() {
+        return runShellCommand("package", mArgs);
+    }
+
     /**
      * Execute the list sub-command.
      *
@@ -317,6 +518,10 @@
         return runShellCommand("package", mArgs);
     }
 
+    private int runUninstall() {
+        return runShellCommand("package", mArgs);
+    }
+
     private int runPath() {
         int userId = UserHandle.USER_SYSTEM;
         String option = nextOption();
@@ -324,8 +529,7 @@
             String optionData = nextOptionData();
             if (optionData == null || !isNumber(optionData)) {
                 System.err.println("Error: no USER_ID specified");
-                showUsage();
-                return 1;
+                return showUsage();
             } else {
                 userId = Integer.parseInt(optionData);
             }
@@ -371,49 +575,6 @@
         }
     }
 
-    /**
-     * Converts a failure code into a string by using reflection to find a matching constant
-     * in PackageManager.
-     */
-    private String installFailureToString(LocalPackageInstallObserver obs) {
-        final int result = obs.result;
-        Field[] fields = PackageManager.class.getFields();
-        for (Field f: fields) {
-            if (f.getType() == int.class) {
-                int modifiers = f.getModifiers();
-                // only look at public final static fields.
-                if (((modifiers & Modifier.FINAL) != 0) &&
-                        ((modifiers & Modifier.PUBLIC) != 0) &&
-                        ((modifiers & Modifier.STATIC) != 0)) {
-                    String fieldName = f.getName();
-                    if (fieldName.startsWith("INSTALL_FAILED_") ||
-                            fieldName.startsWith("INSTALL_PARSE_FAILED_")) {
-                        // get the int value and compare it to result.
-                        try {
-                            if (result == f.getInt(null)) {
-                                StringBuilder sb = new StringBuilder(64);
-                                sb.append(fieldName);
-                                if (obs.extraPermission != null) {
-                                    sb.append(" perm=");
-                                    sb.append(obs.extraPermission);
-                                }
-                                if (obs.extraPackage != null) {
-                                    sb.append(" pkg=" + obs.extraPackage);
-                                }
-                                return sb.toString();
-                            }
-                        } catch (IllegalAccessException e) {
-                            // this shouldn't happen since we only look for public static fields.
-                        }
-                    }
-                }
-            }
-        }
-
-        // couldn't find a matching constant? return the value
-        return Integer.toString(result);
-    }
-
     // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
     private int runSetAppLink() {
         int userId = UserHandle.USER_SYSTEM;
@@ -428,8 +589,7 @@
                 }
             } else {
                 System.err.println("Error: unknown option: " + opt);
-                showUsage();
-                return 1;
+                return showUsage();
             }
         }
 
@@ -437,16 +597,14 @@
         final String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package specified.");
-            showUsage();
-            return 1;
+            return showUsage();
         }
 
         // State to apply; {always|ask|never|undefined}, required
         final String modeString = nextArg();
         if (modeString == null) {
             System.err.println("Error: no app link state specified.");
-            showUsage();
-            return 1;
+            return showUsage();
         }
 
         final int newMode;
@@ -515,8 +673,7 @@
                 }
             } else {
                 System.err.println("Error: unknown option: " + opt);
-                showUsage();
-                return 1;
+                return showUsage();
             }
         }
 
@@ -524,8 +681,7 @@
         final String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package specified.");
-            showUsage();
-            return 1;
+            return showUsage();
         }
 
         try {
@@ -608,316 +764,6 @@
         }
     }
 
-    private int runInstall() {
-        int installFlags = 0;
-        int userId = UserHandle.USER_ALL;
-        String installerPackageName = null;
-
-        String opt;
-
-        String originatingUriString = null;
-        String referrer = null;
-        String abi = null;
-
-        while ((opt=nextOption()) != null) {
-            if (opt.equals("-l")) {
-                installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
-            } else if (opt.equals("-r")) {
-                installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
-            } else if (opt.equals("-i")) {
-                installerPackageName = nextOptionData();
-                if (installerPackageName == null) {
-                    System.err.println("Error: no value specified for -i");
-                    return 1;
-                }
-            } else if (opt.equals("-t")) {
-                installFlags |= PackageManager.INSTALL_ALLOW_TEST;
-            } else if (opt.equals("-s")) {
-                // Override if -s option is specified.
-                installFlags |= PackageManager.INSTALL_EXTERNAL;
-            } else if (opt.equals("-f")) {
-                // Override if -s option is specified.
-                installFlags |= PackageManager.INSTALL_INTERNAL;
-            } else if (opt.equals("-d")) {
-                installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
-            } else if (opt.equals("-g")) {
-                installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
-            } else if (opt.equals("--originating-uri")) {
-                originatingUriString = nextOptionData();
-                if (originatingUriString == null) {
-                    System.err.println("Error: must supply argument for --originating-uri");
-                    return 1;
-                }
-            } else if (opt.equals("--referrer")) {
-                referrer = nextOptionData();
-                if (referrer == null) {
-                    System.err.println("Error: must supply argument for --referrer");
-                    return 1;
-                }
-            } else if (opt.equals("--abi")) {
-                abi = checkAbiArgument(nextOptionData());
-            } else if (opt.equals("--user")) {
-                userId = Integer.parseInt(nextOptionData());
-            } else {
-                System.err.println("Error: Unknown option: " + opt);
-                return 1;
-            }
-        }
-
-        userId = translateUserId(userId, "runInstall");
-        if (userId == UserHandle.USER_ALL) {
-            userId = UserHandle.USER_SYSTEM;
-            installFlags |= PackageManager.INSTALL_ALL_USERS;
-        }
-
-        final Uri verificationURI;
-        final Uri originatingURI;
-        final Uri referrerURI;
-
-        if (originatingUriString != null) {
-            originatingURI = Uri.parse(originatingUriString);
-        } else {
-            originatingURI = null;
-        }
-
-        if (referrer != null) {
-            referrerURI = Uri.parse(referrer);
-        } else {
-            referrerURI = null;
-        }
-
-        // Populate apkURI, must be present
-        final String apkFilePath = nextArg();
-        System.err.println("\tpkg: " + apkFilePath);
-        if (apkFilePath == null) {
-            System.err.println("Error: no package specified");
-            return 1;
-        }
-
-        // Populate verificationURI, optionally present
-        final String verificationFilePath = nextArg();
-        if (verificationFilePath != null) {
-            System.err.println("\tver: " + verificationFilePath);
-            verificationURI = Uri.fromFile(new File(verificationFilePath));
-        } else {
-            verificationURI = null;
-        }
-
-        LocalPackageInstallObserver obs = new LocalPackageInstallObserver();
-        try {
-            VerificationParams verificationParams = new VerificationParams(verificationURI,
-                    originatingURI, referrerURI, VerificationParams.NO_UID, null);
-
-            mPm.installPackageAsUser(apkFilePath, obs.getBinder(), installFlags,
-                    installerPackageName, verificationParams, abi, userId);
-
-            synchronized (obs) {
-                while (!obs.finished) {
-                    try {
-                        obs.wait();
-                    } catch (InterruptedException e) {
-                    }
-                }
-                if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
-                    System.out.println("Success");
-                    return 0;
-                } else {
-                    System.err.println("Failure ["
-                            + installFailureToString(obs)
-                            + "]");
-                    return 1;
-                }
-            }
-        } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(PM_NOT_RUNNING_ERR);
-            return 1;
-        }
-    }
-
-    /**
-     * @param userId The user id to be translated.
-     * @param logContext Optional human readable text to provide some context in error log.
-     * @return Translated concrete user id.  This will include USER_ALL.
-     */
-    private int translateUserId(int userId, String logContext) {
-        return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
-                userId, true, true, logContext, "pm command");
-    }
-
-    private int runInstallCreate() throws RemoteException {
-        int userId = UserHandle.USER_ALL;
-        String installerPackageName = null;
-
-        final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
-
-        String opt;
-        while ((opt = nextOption()) != null) {
-            if (opt.equals("-l")) {
-                params.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
-            } else if (opt.equals("-r")) {
-                params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
-            } else if (opt.equals("-i")) {
-                installerPackageName = nextArg();
-                if (installerPackageName == null) {
-                    throw new IllegalArgumentException("Missing installer package");
-                }
-            } else if (opt.equals("-t")) {
-                params.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
-            } else if (opt.equals("-s")) {
-                params.installFlags |= PackageManager.INSTALL_EXTERNAL;
-            } else if (opt.equals("-f")) {
-                params.installFlags |= PackageManager.INSTALL_INTERNAL;
-            } else if (opt.equals("-d")) {
-                params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
-            } else if (opt.equals("-g")) {
-                params.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
-            } else if (opt.equals("--originating-uri")) {
-                params.originatingUri = Uri.parse(nextOptionData());
-            } else if (opt.equals("--referrer")) {
-                params.referrerUri = Uri.parse(nextOptionData());
-            } else if (opt.equals("-p")) {
-                params.mode = SessionParams.MODE_INHERIT_EXISTING;
-                params.appPackageName = nextOptionData();
-                if (params.appPackageName == null) {
-                    throw new IllegalArgumentException("Missing inherit package name");
-                }
-            } else if (opt.equals("-S")) {
-                params.setSize(Long.parseLong(nextOptionData()));
-            } else if (opt.equals("--abi")) {
-                params.abiOverride = checkAbiArgument(nextOptionData());
-            } else if (opt.equals("--user")) {
-                userId = Integer.parseInt(nextOptionData());
-            } else if (opt.equals("--install-location")) {
-                params.installLocation = Integer.parseInt(nextOptionData());
-            } else if (opt.equals("--force-uuid")) {
-                params.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
-                params.volumeUuid = nextOptionData();
-                if ("internal".equals(params.volumeUuid)) {
-                    params.volumeUuid = null;
-                }
-            } else {
-                throw new IllegalArgumentException("Unknown option " + opt);
-            }
-        }
-
-        userId = translateUserId(userId, "runInstallCreate");
-        if (userId == UserHandle.USER_ALL) {
-            userId = UserHandle.USER_SYSTEM;
-            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
-        }
-
-        final int sessionId = mInstaller.createSession(params, installerPackageName, userId);
-
-        // NOTE: adb depends on parsing this string
-        System.out.println("Success: created install session [" + sessionId + "]");
-        return 0;
-    }
-
-    private int runInstallWrite() throws IOException, RemoteException {
-        long sizeBytes = -1;
-
-        String opt;
-        while ((opt = nextOption()) != null) {
-            if (opt.equals("-S")) {
-                sizeBytes = Long.parseLong(nextOptionData());
-            } else {
-                throw new IllegalArgumentException("Unknown option: " + opt);
-            }
-        }
-
-        final int sessionId = Integer.parseInt(nextArg());
-        final String splitName = nextArg();
-
-        String path = nextArg();
-        if ("-".equals(path)) {
-            path = null;
-        } else if (path != null) {
-            final File file = new File(path);
-            if (file.isFile()) {
-                sizeBytes = file.length();
-            }
-        }
-
-        final SessionInfo info = mInstaller.getSessionInfo(sessionId);
-
-        PackageInstaller.Session session = null;
-        InputStream in = null;
-        OutputStream out = null;
-        try {
-            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
-
-            if (path != null) {
-                in = new FileInputStream(path);
-            } else {
-                in = new SizedInputStream(System.in, sizeBytes);
-            }
-            out = session.openWrite(splitName, 0, sizeBytes);
-
-            int total = 0;
-            byte[] buffer = new byte[65536];
-            int c;
-            while ((c = in.read(buffer)) != -1) {
-                total += c;
-                out.write(buffer, 0, c);
-
-                if (info.sizeBytes > 0) {
-                    final float fraction = ((float) c / (float) info.sizeBytes);
-                    session.addProgress(fraction);
-                }
-            }
-            session.fsync(out);
-
-            System.out.println("Success: streamed " + total + " bytes");
-            return 0;
-        } finally {
-            IoUtils.closeQuietly(out);
-            IoUtils.closeQuietly(in);
-            IoUtils.closeQuietly(session);
-        }
-    }
-
-    private int runInstallCommit() throws RemoteException {
-        final int sessionId = Integer.parseInt(nextArg());
-
-        PackageInstaller.Session session = null;
-        try {
-            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
-
-            final LocalIntentReceiver receiver = new LocalIntentReceiver();
-            session.commit(receiver.getIntentSender());
-
-            final Intent result = receiver.getResult();
-            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
-                    PackageInstaller.STATUS_FAILURE);
-            if (status == PackageInstaller.STATUS_SUCCESS) {
-                System.out.println("Success");
-                return 0;
-            } else {
-                Log.e(TAG, "Failure details: " + result.getExtras());
-                System.err.println("Failure ["
-                        + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
-                return 1;
-            }
-        } finally {
-            IoUtils.closeQuietly(session);
-        }
-    }
-
-    private int runInstallAbandon() throws RemoteException {
-        final int sessionId = Integer.parseInt(nextArg());
-
-        PackageInstaller.Session session = null;
-        try {
-            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
-            session.abandon();
-            System.out.println("Success");
-            return 0;
-        } finally {
-            IoUtils.closeQuietly(session);
-        }
-    }
-
     private int runSetInstaller() throws RemoteException {
         final String targetPackage = nextArg();
         final String installerPackageName = nextArg();
@@ -942,8 +788,7 @@
                 String optionData = nextOptionData();
                 if (optionData == null || !isNumber(optionData)) {
                     System.err.println("Error: no USER_ID specified");
-                    showUsage();
-                    return 1;
+                    return showUsage();
                 } else {
                     userId = Integer.parseInt(optionData);
                 }
@@ -953,8 +798,7 @@
                 flags |= UserInfo.FLAG_RESTRICTED;
             } else {
                 System.err.println("Error: unknown option " + opt);
-                showUsage();
-                return 1;
+                return showUsage();
             }
         }
         String arg = nextArg();
@@ -1088,81 +932,6 @@
         }
     }
 
-    private int runUninstall() throws RemoteException {
-        int flags = 0;
-        int userId = UserHandle.USER_ALL;
-
-        String opt;
-        while ((opt=nextOption()) != null) {
-            if (opt.equals("-k")) {
-                flags |= PackageManager.DELETE_KEEP_DATA;
-            } else if (opt.equals("--user")) {
-                String param = nextArg();
-                if (isNumber(param)) {
-                    userId = Integer.parseInt(param);
-                } else {
-                    showUsage();
-                    System.err.println("Error: Invalid user: " + param);
-                    return 1;
-                }
-            } else {
-                System.err.println("Error: Unknown option: " + opt);
-                return 1;
-            }
-        }
-
-        String pkg = nextArg();
-        if (pkg == null) {
-            System.err.println("Error: no package specified");
-            showUsage();
-            return 1;
-        }
-
-        userId = translateUserId(userId, "runUninstall");
-        if (userId == UserHandle.USER_ALL) {
-            userId = UserHandle.USER_SYSTEM;
-            flags |= PackageManager.DELETE_ALL_USERS;
-        } else {
-            PackageInfo info;
-            try {
-                info = mPm.getPackageInfo(pkg, 0, userId);
-            } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(PM_NOT_RUNNING_ERR);
-                return 1;
-            }
-            if (info == null) {
-                System.err.println("Failure - not installed for " + userId);
-                return 1;
-            }
-            final boolean isSystem =
-                    (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-            // If we are being asked to delete a system app for just one
-            // user set flag so it disables rather than reverting to system
-            // version of the app.
-            if (isSystem) {
-                flags |= PackageManager.DELETE_SYSTEM_APP;
-            }
-        }
-
-        final LocalIntentReceiver receiver = new LocalIntentReceiver();
-        mInstaller.uninstall(pkg, null /* callerPackageName */, flags,
-                receiver.getIntentSender(), userId);
-
-        final Intent result = receiver.getResult();
-        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
-                PackageInstaller.STATUS_FAILURE);
-        if (status == PackageInstaller.STATUS_SUCCESS) {
-            System.out.println("Success");
-            return 0;
-        } else {
-            Log.e(TAG, "Failure details: " + result.getExtras());
-            System.err.println("Failure ["
-                    + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
-            return 1;
-        }
-    }
-
     static class ClearDataObserver extends IPackageDataObserver.Stub {
         boolean finished;
         boolean result;
@@ -1184,8 +953,7 @@
             String optionData = nextOptionData();
             if (optionData == null || !isNumber(optionData)) {
                 System.err.println("Error: no USER_ID specified");
-                showUsage();
-                return 1;
+                return showUsage();
             } else {
                 userId = Integer.parseInt(optionData);
             }
@@ -1194,8 +962,7 @@
         String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
 
         ClearDataObserver obs = new ClearDataObserver();
@@ -1256,8 +1023,7 @@
             String optionData = nextOptionData();
             if (optionData == null || !isNumber(optionData)) {
                 System.err.println("Error: no USER_ID specified");
-                showUsage();
-                return 1;
+                return showUsage();
             } else {
                 userId = Integer.parseInt(optionData);
             }
@@ -1266,8 +1032,7 @@
         String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package or component specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
         ComponentName cn = ComponentName.unflattenFromString(pkg);
         if (cn == null) {
@@ -1305,8 +1070,7 @@
             String optionData = nextOptionData();
             if (optionData == null || !isNumber(optionData)) {
                 System.err.println("Error: no USER_ID specified");
-                showUsage();
-                return 1;
+                return showUsage();
             } else {
                 userId = Integer.parseInt(optionData);
             }
@@ -1315,8 +1079,7 @@
         String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package or component specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
         try {
             mPm.setApplicationHiddenSettingAsUser(pkg, state, userId);
@@ -1343,14 +1106,12 @@
         String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
         String perm = nextArg();
         if (perm == null) {
             System.err.println("Error: no permission specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
 
         try {
@@ -1366,8 +1127,7 @@
             return 1;
         } catch (IllegalArgumentException e) {
             System.err.println("Bad argument: " + e.toString());
-            showUsage();
-            return 1;
+            return showUsage();
         } catch (SecurityException e) {
             System.err.println("Operation not allowed: " + e.toString());
             return 1;
@@ -1384,8 +1144,7 @@
             return 1;
         } catch (IllegalArgumentException e) {
             System.err.println("Bad argument: " + e.toString());
-            showUsage();
-            return 1;
+            return showUsage();
         } catch (SecurityException e) {
             System.err.println("Operation not allowed: " + e.toString());
             return 1;
@@ -1396,14 +1155,12 @@
         final String permission = nextArg();
         if (permission == null) {
             System.err.println("Error: no permission specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
         final String enforcedRaw = nextArg();
         if (enforcedRaw == null) {
             System.err.println("Error: no enforcement specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
         final boolean enforced = Boolean.parseBoolean(enforcedRaw);
         try {
@@ -1415,8 +1172,7 @@
             return 1;
         } catch (IllegalArgumentException e) {
             System.err.println("Bad argument: " + e.toString());
-            showUsage();
-            return 1;
+            return showUsage();
         } catch (SecurityException e) {
             System.err.println("Operation not allowed: " + e.toString());
             return 1;
@@ -1442,8 +1198,7 @@
         String size = nextArg();
         if (size == null) {
             System.err.println("Error: no size specified");
-            showUsage();
-            return 1;
+            return showUsage();
         }
         int len = size.length();
         long multiplier = 1;
@@ -1457,8 +1212,7 @@
                 multiplier = 1024L*1024L*1024L;
             } else {
                 System.err.println("Invalid suffix: " + c);
-                showUsage();
-                return 1;
+                return showUsage();
             }
             size = size.substring(0, len-1);
         }
@@ -1467,8 +1221,7 @@
             sizeVal = Long.parseLong(size) * multiplier;
         } catch (NumberFormatException e) {
             System.err.println("Error: expected number at: " + size);
-            showUsage();
-            return 1;
+            return showUsage();
         }
         String volumeUuid = nextArg();
         if ("internal".equals(volumeUuid)) {
@@ -1492,8 +1245,7 @@
             return 1;
         } catch (IllegalArgumentException e) {
             System.err.println("Bad argument: " + e.toString());
-            showUsage();
-            return 1;
+            return showUsage();
         } catch (SecurityException e) {
             System.err.println("Operation not allowed: " + e.toString());
             return 1;
@@ -1525,54 +1277,6 @@
         return 1;
     }
 
-    private static String checkAbiArgument(String abi) {
-        if (TextUtils.isEmpty(abi)) {
-            throw new IllegalArgumentException("Missing ABI argument");
-        }
-
-        if ("-".equals(abi)) {
-            return abi;
-        }
-
-        final String[] supportedAbis = Build.SUPPORTED_ABIS;
-        for (String supportedAbi : supportedAbis) {
-            if (supportedAbi.equals(abi)) {
-                return abi;
-            }
-        }
-
-        throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
-    }
-
-    private static class LocalIntentReceiver {
-        private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
-
-        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
-            @Override
-            public int send(int code, Intent intent, String resolvedType,
-                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
-                try {
-                    mResult.offer(intent, 5, TimeUnit.SECONDS);
-                } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
-                }
-                return 0;
-            }
-        };
-
-        public IntentSender getIntentSender() {
-            return new IntentSender((IIntentSender) mLocalSender);
-        }
-
-        public Intent getResult() {
-            try {
-                return mResult.take();
-            } catch (InterruptedException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
     private String nextOption() {
         if (mNextArg >= mArgs.length) {
             return null;
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 0a1ba4d1..b208e43 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -42,6 +42,7 @@
         } catch (Exception e) {
             if (e instanceof IllegalArgumentException) {
                 showUsage();
+                System.exit(1);
             }
             Log.e(TAG, "Error", e);
             System.err.println("Error: " + e);
@@ -85,6 +86,8 @@
             runBenchmark();
         } else if ("forget".equals(op)) {
             runForget();
+        } else if ("set-emulate-fbe".equals(op)) {
+            runSetEmulateFbe();
         } else {
             throw new IllegalArgumentException();
         }
@@ -136,6 +139,12 @@
                 StorageManager.DEBUG_FORCE_ADOPTABLE);
     }
 
+    public void runSetEmulateFbe() throws RemoteException {
+        final boolean emulateFbe = Boolean.parseBoolean(nextArg());
+        mSm.setDebugFlags(emulateFbe ? StorageManager.DEBUG_EMULATE_FBE : 0,
+                StorageManager.DEBUG_EMULATE_FBE);
+    }
+
     public void runPartition() throws RemoteException {
         final String diskId = nextArg();
         final String type = nextArg();
@@ -204,6 +213,8 @@
         System.err.println("");
         System.err.println("       sm forget [UUID|all]");
         System.err.println("");
+        System.err.println("       sm set-emulate-fbe [true|false]");
+        System.err.println("");
         return 1;
     }
 }
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 6f65889..7f9a5d3 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -955,7 +955,6 @@
         mStarted = true;
         mPaused = false;
         mRunning = false;
-        mAnimationEndRequested = false;
         AnimationHandler animationHandler = AnimationHandler.getInstance();
         animationHandler.addAnimationFrameCallback(this, (long) (mStartDelay * sDurationScale));
 
@@ -1123,6 +1122,8 @@
             Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
                     System.identityHashCode(this));
         }
+
+        mAnimationEndRequested = false;
         initAnimation();
         mRunning = true;
         if (mSeekFraction >= 0) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b809baa..65de4ca 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1531,14 +1531,100 @@
         }
     }
 
+    /**
+     * Metadata related to the {@link TaskThumbnail}.
+     *
+     * @hide
+     */
+    public static class TaskThumbnailInfo implements Parcelable {
+        /** @hide */
+        public static final String ATTR_TASK_THUMBNAILINFO_PREFIX = "task_thumbnailinfo_";
+        private static final String ATTR_TASK_WIDTH =
+                ATTR_TASK_THUMBNAILINFO_PREFIX + "task_width";
+        private static final String ATTR_TASK_HEIGHT =
+                ATTR_TASK_THUMBNAILINFO_PREFIX + "task_height";
+        private static final String ATTR_SCREEN_ORIENTATION =
+                ATTR_TASK_THUMBNAILINFO_PREFIX + "screen_orientation";
+
+        public int taskWidth;
+        public int taskHeight;
+        public int screenOrientation;
+
+        public TaskThumbnailInfo() {
+            // Do nothing
+        }
+
+        private TaskThumbnailInfo(Parcel source) {
+            readFromParcel(source);
+        }
+
+        /**
+         * Resets this info state to the initial state.
+         * @hide
+         */
+        public void reset() {
+            taskWidth = 0;
+            taskHeight = 0;
+            screenOrientation = 0;
+        }
+
+        /** @hide */
+        public void saveToXml(XmlSerializer out) throws IOException {
+            out.attribute(null, ATTR_TASK_WIDTH, Integer.toString(taskWidth));
+            out.attribute(null, ATTR_TASK_HEIGHT, Integer.toString(taskHeight));
+            out.attribute(null, ATTR_SCREEN_ORIENTATION, Integer.toString(screenOrientation));
+        }
+
+        /** @hide */
+        public void restoreFromXml(String attrName, String attrValue) {
+            if (ATTR_TASK_WIDTH.equals(attrName)) {
+                taskWidth = Integer.parseInt(attrValue);
+            } else if (ATTR_TASK_HEIGHT.equals(attrName)) {
+                taskHeight = Integer.parseInt(attrValue);
+            } else if (ATTR_SCREEN_ORIENTATION.equals(attrName)) {
+                screenOrientation = Integer.parseInt(attrValue);
+            }
+        }
+
+        public int describeContents() {
+            return 0;
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(taskWidth);
+            dest.writeInt(taskHeight);
+            dest.writeInt(screenOrientation);
+        }
+
+        public void readFromParcel(Parcel source) {
+            taskWidth = source.readInt();
+            taskHeight = source.readInt();
+            screenOrientation = source.readInt();
+        }
+
+        public static final Creator<TaskThumbnailInfo> CREATOR = new Creator<TaskThumbnailInfo>() {
+            public TaskThumbnailInfo createFromParcel(Parcel source) {
+                return new TaskThumbnailInfo(source);
+            }
+            public TaskThumbnailInfo[] newArray(int size) {
+                return new TaskThumbnailInfo[size];
+            }
+        };
+    }
+
     /** @hide */
     public static class TaskThumbnail implements Parcelable {
         public Bitmap mainThumbnail;
         public ParcelFileDescriptor thumbnailFileDescriptor;
+        public TaskThumbnailInfo thumbnailInfo;
 
         public TaskThumbnail() {
         }
 
+        private TaskThumbnail(Parcel source) {
+            readFromParcel(source);
+        }
+
         public int describeContents() {
             if (thumbnailFileDescriptor != null) {
                 return thumbnailFileDescriptor.describeContents();
@@ -1559,6 +1645,12 @@
             } else {
                 dest.writeInt(0);
             }
+            if (thumbnailInfo != null) {
+                dest.writeInt(1);
+                thumbnailInfo.writeToParcel(dest, flags);
+            } else {
+                dest.writeInt(0);
+            }
         }
 
         public void readFromParcel(Parcel source) {
@@ -1572,6 +1664,11 @@
             } else {
                 thumbnailFileDescriptor = null;
             }
+            if (source.readInt() != 0) {
+                thumbnailInfo = TaskThumbnailInfo.CREATOR.createFromParcel(source);
+            } else {
+                thumbnailInfo = null;
+            }
         }
 
         public static final Creator<TaskThumbnail> CREATOR = new Creator<TaskThumbnail>() {
@@ -1582,10 +1679,6 @@
                 return new TaskThumbnail[size];
             }
         };
-
-        private TaskThumbnail(Parcel source) {
-            readFromParcel(source);
-        }
     }
 
     /** @hide */
@@ -2952,6 +3045,11 @@
         }
     }
 
+    /** {@hide} */
+    public static final int FLAG_OR_STOPPED = 1 << 0;
+    /** {@hide} */
+    public static final int FLAG_WITH_AMNESIA = 1 << 1;
+
     /**
      * Return whether the given user is actively running.  This means that
      * the user is in the "started" state, not "stopped" -- it is currently
@@ -2963,7 +3061,7 @@
      */
     public boolean isUserRunning(int userid) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(userid, false);
+            return ActivityManagerNative.getDefault().isUserRunning(userid, 0);
         } catch (RemoteException e) {
             return false;
         }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 7c3fcc3..4449e4f 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -769,7 +769,11 @@
         case RESIZE_STACK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             final int stackId = data.readInt();
-            Rect r = Rect.CREATOR.createFromParcel(data);
+            final boolean hasRect = data.readInt() != 0;
+            Rect r = null;
+            if (hasRect) {
+                r = Rect.CREATOR.createFromParcel(data);
+            }
             final boolean allowResizeInDockedMode = data.readInt() == 1;
             resizeStack(stackId, r, allowResizeInDockedMode);
             reply.writeNoException();
@@ -1980,8 +1984,8 @@
         case IS_USER_RUNNING_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int userid = data.readInt();
-            boolean orStopping = data.readInt() != 0;
-            boolean result = isUserRunning(userid, orStopping);
+            int _flags = data.readInt();
+            boolean result = isUserRunning(userid, _flags);
             reply.writeNoException();
             reply.writeInt(result ? 1 : 0);
             return true;
@@ -3590,7 +3594,12 @@
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(stackId);
-        r.writeToParcel(data, 0);
+        if (r != null) {
+            data.writeInt(1);
+            r.writeToParcel(data, 0);
+        } else {
+            data.writeInt(0);
+        }
         data.writeInt(allowResizeInDockedMode ? 1 : 0);
         mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0);
         reply.readException();
@@ -5256,12 +5265,12 @@
         return userInfo;
     }
 
-    public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException {
+    public boolean isUserRunning(int userid, int flags) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(userid);
-        data.writeInt(orStopping ? 1 : 0);
+        data.writeInt(flags);
         mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean result = reply.readInt() != 0;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index a74f528..b3d6382 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4834,13 +4834,7 @@
         // Continue loading instrumentation.
         if (ii != null) {
             final ApplicationInfo instrApp = new ApplicationInfo();
-            instrApp.packageName = ii.packageName;
-            instrApp.sourceDir = ii.sourceDir;
-            instrApp.publicSourceDir = ii.publicSourceDir;
-            instrApp.splitSourceDirs = ii.splitSourceDirs;
-            instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
-            instrApp.dataDir = ii.dataDir;
-            instrApp.nativeLibraryDir = ii.nativeLibraryDir;
+            ii.copyTo(instrApp);
 
             final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                     appContext.getClassLoader(), false, true, false);
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 371c923..c075ed6 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -24,8 +24,6 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.graphics.SurfaceTexture;
-import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.OperationCanceledException;
@@ -45,6 +43,17 @@
 import dalvik.system.CloseGuard;
 
 import java.lang.ref.WeakReference;
+import java.util.ArrayDeque;
+import java.util.concurrent.Executor;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.android.internal.annotations.GuardedBy;
+
 
 /** @hide */
 public class ActivityView extends ViewGroup {
@@ -53,9 +62,64 @@
 
     private static final int MSG_SET_SURFACE = 1;
 
-    DisplayMetrics mMetrics = new DisplayMetrics();
+    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
+    private static final int MINIMUM_POOL_SIZE = 1;
+    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
+    private static final int KEEP_ALIVE = 1;
+
+    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
+        private final AtomicInteger mCount = new AtomicInteger(1);
+
+        public Thread newThread(Runnable r) {
+            return new Thread(r, "ActivityView #" + mCount.getAndIncrement());
+        }
+    };
+
+    private static final BlockingQueue<Runnable> sPoolWorkQueue =
+            new LinkedBlockingQueue<Runnable>(128);
+
+    /**
+     * An {@link Executor} that can be used to execute tasks in parallel.
+     */
+    private static final Executor sExecutor = new ThreadPoolExecutor(MINIMUM_POOL_SIZE,
+            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
+
+
+    private static class SerialExecutor implements Executor {
+        private final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
+        private Runnable mActive;
+
+        public synchronized void execute(final Runnable r) {
+            mTasks.offer(new Runnable() {
+                public void run() {
+                    try {
+                        r.run();
+                    } finally {
+                        scheduleNext();
+                    }
+                }
+            });
+            if (mActive == null) {
+                scheduleNext();
+            }
+        }
+
+        protected synchronized void scheduleNext() {
+            if ((mActive = mTasks.poll()) != null) {
+                sExecutor.execute(mActive);
+            }
+        }
+    }
+
+    private final SerialExecutor mExecutor = new SerialExecutor();
+
+    private final int mDensityDpi;
     private final TextureView mTextureView;
+
+    @GuardedBy("mActivityContainerLock")
     private ActivityContainerWrapper mActivityContainer;
+    private Object mActivityContainerLock = new Object();
+
     private Activity mActivity;
     private int mWidth;
     private int mHeight;
@@ -63,8 +127,6 @@
     private int mLastVisibility;
     private ActivityViewCallback mActivityViewCallback;
 
-    private HandlerThread mThread = new HandlerThread("ActivityViewThread");
-    private Handler mHandler;
 
     public ActivityView(Context context) {
         this(context, null);
@@ -97,28 +159,14 @@
                     + e);
         }
 
-        mThread.start();
-        mHandler = new Handler(mThread.getLooper()) {
-            @Override
-            public void handleMessage(Message msg) {
-                super.handleMessage(msg);
-                if (msg.what == MSG_SET_SURFACE) {
-                    try {
-                        mActivityContainer.setSurface((Surface) msg.obj, msg.arg1, msg.arg2,
-                                mMetrics.densityDpi);
-                    } catch (RemoteException e) {
-                        throw new RuntimeException(
-                                "ActivityView: Unable to set surface of ActivityContainer. " + e);
-                    }
-                }
-            }
-        };
         mTextureView = new TextureView(context);
         mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
         addView(mTextureView);
 
         WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
-        wm.getDefaultDisplay().getMetrics(mMetrics);
+        DisplayMetrics metrics = new DisplayMetrics();
+        wm.getDefaultDisplay().getMetrics(metrics);
+        mDensityDpi = metrics.densityDpi;
 
         mLastVisibility = getVisibility();
 
@@ -131,15 +179,13 @@
     }
 
     @Override
-    protected void onVisibilityChanged(View changedView, int visibility) {
+    protected void onVisibilityChanged(View changedView, final int visibility) {
         super.onVisibilityChanged(changedView, visibility);
 
         if (mSurface != null && (visibility == View.GONE || mLastVisibility == View.GONE)) {
-            Message msg = Message.obtain(mHandler, MSG_SET_SURFACE);
-            msg.obj = (visibility == View.GONE) ? null : mSurface;
-            msg.arg1 = mWidth;
-            msg.arg2 = mHeight;
-            mHandler.sendMessage(msg);
+            if (DEBUG) Log.v(TAG, "visibility changed; enqueing runnable");
+            final Surface surface = (visibility == View.GONE) ? null : mSurface;
+            setSurfaceAsync(surface, mWidth, mHeight, mDensityDpi, false);
         }
         mLastVisibility = visibility;
     }
@@ -230,8 +276,10 @@
             Log.e(TAG, "Duplicate call to release");
             return;
         }
-        mActivityContainer.release();
-        mActivityContainer = null;
+        synchronized (mActivityContainerLock) {
+            mActivityContainer.release();
+            mActivityContainer = null;
+        }
 
         if (mSurface != null) {
             mSurface.release();
@@ -239,25 +287,39 @@
         }
 
         mTextureView.setSurfaceTextureListener(null);
-
-        mThread.quit();
     }
 
-    private void attachToSurfaceWhenReady() {
-        final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
-        if (surfaceTexture == null || mSurface != null) {
-            // Either not ready to attach, or already attached.
-            return;
-        }
-
-        mSurface = new Surface(surfaceTexture);
-        try {
-            mActivityContainer.setSurface(mSurface, mWidth, mHeight, mMetrics.densityDpi);
-        } catch (RemoteException e) {
-            mSurface.release();
-            mSurface = null;
-            throw new RuntimeException("ActivityView: Unable to create ActivityContainer. " + e);
-        }
+    private void setSurfaceAsync(final Surface surface, final int width, final int height,
+            final int densityDpi, final boolean callback) {
+        mExecutor.execute(new Runnable() {
+            public void run() {
+                try {
+                    synchronized (mActivityContainerLock) {
+                        if (mActivityContainer != null) {
+                            mActivityContainer.setSurface(surface, width, height, densityDpi);
+                        }
+                    }
+                } catch (RemoteException e) {
+                    throw new RuntimeException(
+                        "ActivityView: Unable to set surface of ActivityContainer. ",
+                        e);
+                }
+                if (callback) {
+                    post(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (mActivityViewCallback != null) {
+                                if (surface != null) {
+                                    mActivityViewCallback.onSurfaceAvailable(ActivityView.this);
+                                } else {
+                                    mActivityViewCallback.onSurfaceDestroyed(ActivityView.this);
+                                }
+                            }
+                        }
+                    });
+                }
+            }
+        });
     }
 
     /**
@@ -308,10 +370,8 @@
                     + height);
             mWidth = width;
             mHeight = height;
-            attachToSurfaceWhenReady();
-            if (mActivityViewCallback != null) {
-                mActivityViewCallback.onSurfaceAvailable(ActivityView.this);
-            }
+            mSurface = new Surface(surfaceTexture);
+            setSurfaceAsync(mSurface, mWidth, mHeight, mDensityDpi, true);
         }
 
         @Override
@@ -331,15 +391,7 @@
             if (DEBUG) Log.d(TAG, "onSurfaceTextureDestroyed");
             mSurface.release();
             mSurface = null;
-            try {
-                mActivityContainer.setSurface(null, mWidth, mHeight, mMetrics.densityDpi);
-            } catch (RemoteException e) {
-                throw new RuntimeException(
-                        "ActivityView: Unable to set surface of ActivityContainer. " + e);
-            }
-            if (mActivityViewCallback != null) {
-                mActivityViewCallback.onSurfaceDestroyed(ActivityView.this);
-            }
+            setSurfaceAsync(null, mWidth, mHeight, mDensityDpi, true);
             return true;
         }
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index fca5567..bc7c3d0 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -443,6 +443,22 @@
     }
 
     @Override
+    public File getDeviceEncryptedFilesDir() {
+        if (mPackageInfo != null) {
+            return mPackageInfo.getDeviceEncryptedDataDirFile();
+        }
+        throw new RuntimeException("Not supported in system context");
+    }
+
+    @Override
+    public File getCredentialEncryptedFilesDir() {
+        if (mPackageInfo != null) {
+            return mPackageInfo.getCredentialEncryptedDataDirFile();
+        }
+        throw new RuntimeException("Not supported in system context");
+    }
+
+    @Override
     public File getNoBackupFilesDir() {
         synchronized (mSync) {
             if (mNoBackupFilesDir == null) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index fcc040b..b69a480 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -392,7 +392,7 @@
     public boolean startUserInBackground(int userid) throws RemoteException;
     public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
     public UserInfo getCurrentUser() throws RemoteException;
-    public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
+    public boolean isUserRunning(int userid, int flags) throws RemoteException;
     public int[] getRunningUserIds() throws RemoteException;
 
     public boolean removeTask(int taskId) throws RemoteException;
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index c2bf28a..891558f 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -31,6 +31,7 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Resources;
 import android.os.Bundle;
+import android.os.FileUtils;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Process;
@@ -93,6 +94,8 @@
     private final String mDataDir;
     private final String mLibDir;
     private final File mDataDirFile;
+    private final File mDeviceEncryptedDataDirFile;
+    private final File mCredentialEncryptedDataDirFile;
     private final ClassLoader mBaseClassLoader;
     private final boolean mSecurityViolation;
     private final boolean mIncludeCode;
@@ -139,7 +142,9 @@
         mOverlayDirs = aInfo.resourceDirs;
         mSharedLibraries = aInfo.sharedLibraryFiles;
         mDataDir = aInfo.dataDir;
-        mDataDirFile = mDataDir != null ? new File(mDataDir) : null;
+        mDataDirFile = FileUtils.newFileOrNull(mDataDir);
+        mDeviceEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceEncryptedDataDir);
+        mCredentialEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialEncryptedDataDir);
         mLibDir = aInfo.nativeLibraryDir;
         mBaseClassLoader = baseLoader;
         mSecurityViolation = securityViolation;
@@ -192,6 +197,8 @@
         mSharedLibraries = null;
         mDataDir = null;
         mDataDirFile = null;
+        mDeviceEncryptedDataDirFile = null;
+        mCredentialEncryptedDataDirFile = null;
         mLibDir = null;
         mBaseClassLoader = null;
         mSecurityViolation = false;
@@ -268,7 +275,7 @@
                 if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) {
                     final String isa = VMRuntime.getRuntime().vmInstructionSet();
                     try {
-                        ActivityThread.getPackageManager().performDexOptIfNeeded(mPackageName, isa);
+                        ActivityThread.getPackageManager().notifyPackageUse(mPackageName);
                     } catch (RemoteException re) {
                         // Ignored.
                     }
@@ -539,6 +546,14 @@
         return mDataDirFile;
     }
 
+    public File getDeviceEncryptedDataDirFile() {
+        return mDeviceEncryptedDataDirFile;
+    }
+
+    public File getCredentialEncryptedDataDirFile() {
+        return mCredentialEncryptedDataDirFile;
+    }
+
     public AssetManager getAssets(ActivityThread mainThread) {
         return getResources(mainThread).getAssets();
     }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5a75640..0b77be3 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2599,6 +2599,12 @@
             mN.ledARGB = argb;
             mN.ledOnMS = onMs;
             mN.ledOffMS = offMs;
+            if (onMs != 0 || offMs != 0) {
+                mN.flags |= FLAG_SHOW_LIGHTS;
+            }
+            if ((mN.defaults & DEFAULT_LIGHTS) != 0) {
+                mN.flags |= FLAG_SHOW_LIGHTS;
+            }
             return this;
         }
 
@@ -2951,6 +2957,7 @@
          */
         public Builder setColor(@ColorInt int argb) {
             mN.color = argb;
+            sanitizeColor();
             return this;
         }
 
@@ -3419,11 +3426,10 @@
             }
         }
 
-        private int sanitizeColor() {
+        private void sanitizeColor() {
             if (mN.color != COLOR_DEFAULT) {
                 mN.color |= 0xFF000000; // no alpha for custom colors
             }
-            return mN.color;
         }
 
         private int resolveColor() {
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index c42ba65..edafe59 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -432,7 +432,7 @@
      * @param intents Array of Intents of the activities to be launched.
      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
-     * or any of the flags as supported by
+     * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
      * of the intent that can be supplied when the actual send happens.
      *
@@ -502,7 +502,7 @@
      * @param intent The Intent to be broadcast.
      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
-     * or any of the flags as supported by
+     * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
      * of the intent that can be supplied when the actual send happens.
      *
@@ -556,7 +556,7 @@
      * @param intent An Intent describing the service to be started.
      * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
      * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
-     * or any of the flags as supported by
+     * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
      * of the intent that can be supplied when the actual send happens.
      *
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index a3b3022..aca0763 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -23,10 +23,8 @@
 import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.Button;
 import android.widget.TimePicker;
 import android.widget.TimePicker.OnTimeChangedListener;
-import android.widget.TimePicker.ValidationCallback;
 
 import com.android.internal.R;
 
@@ -64,7 +62,7 @@
          * @param hourOfDay the hour that was set
          * @param minute the minute that was set
          */
-        public void onTimeSet(TimePicker view, int hourOfDay, int minute);
+        void onTimeSet(TimePicker view, int hourOfDay, int minute);
     }
 
     /**
@@ -115,7 +113,6 @@
 
         final TypedValue outValue = new TypedValue();
         context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
-        final int layoutResId = outValue.resourceId;
 
         final LayoutInflater inflater = LayoutInflater.from(themeContext);
         final View view = inflater.inflate(R.layout.time_picker_dialog, null);
@@ -129,7 +126,6 @@
         mTimePicker.setCurrentHour(mInitialHourOfDay);
         mTimePicker.setCurrentMinute(mInitialMinute);
         mTimePicker.setOnTimeChangedListener(this);
-        mTimePicker.setValidationCallback(mValidationCallback);
     }
 
     @Override
@@ -181,14 +177,4 @@
         mTimePicker.setCurrentHour(hour);
         mTimePicker.setCurrentMinute(minute);
     }
-
-    private final ValidationCallback mValidationCallback = new ValidationCallback() {
-        @Override
-        public void onValidationChanged(boolean valid) {
-            final Button positive = getButton(BUTTON_POSITIVE);
-            if (positive != null) {
-                positive.setEnabled(valid);
-            }
-        }
-    };
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 0fdf3d3..faed7a0 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -122,7 +122,10 @@
      * Provisioning adds a managed profile and sets the MDM as the profile owner who has full
      * control over the profile.
      *
-     * In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this intent must contain the
+     * <p>It is possible to check if provisioning is allowed or not by querying the method
+     * {@link #isProvisioningAllowed(String)}.
+     *
+     * <p>In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this intent must contain the
      * extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
      * As of {@link android.os.Build.VERSION_CODES#M}, it should contain the extra
      * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, although specifying only
@@ -148,6 +151,31 @@
         = "android.app.action.PROVISION_MANAGED_PROFILE";
 
     /**
+     * @hide
+     * Activity action: Starts the provisioning flow which sets up a managed user.
+     *
+     * <p>This intent will typically be sent by a mobile device management application (MDM).
+     * Provisioning configures the current user as managed user and sets the MDM as the profile
+     * owner who has full control over the user. Provisioning can only happen before user setup has
+     * been completed. Use {@link #isProvisioningAllowed(String)} to check if provisioning is
+     * allowed.
+     *
+     * <p>This intent should contain the extra
+     * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}.
+     *
+     * <p> If provisioning fails, the device returns to its previous state.
+     *
+     * <p>If launched with {@link android.app.Activity#startActivityForResult(Intent, int)} a
+     * result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part of
+     * the provisioning flow was successful, although this doesn't guarantee the full flow will
+     * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies
+     * that the user backed-out of provisioning, or some precondition for provisioning wasn't met.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PROVISION_MANAGED_USER
+        = "android.app.action.PROVISION_MANAGED_USER";
+
+    /**
      * Activity action: Starts the provisioning flow which sets up a managed device.
      * Must be started with {@link android.app.Activity#startActivityForResult(Intent, int)}.
      *
@@ -159,10 +187,10 @@
      * employee or client.
      *
      * <p> An intent with this action can be sent only on an unprovisioned device.
-     * It is possible to check if the device is provisioned or not by looking at
-     * {@link android.provider.Settings.Global#DEVICE_PROVISIONED}
+     * It is possible to check if provisioning is allowed or not by querying the method
+     * {@link #isProvisioningAllowed(String)}.
      *
-     * The intent contains the following extras:
+     * <p>The intent contains the following extras:
      * <ul>
      * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
      * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
@@ -186,6 +214,53 @@
         = "android.app.action.PROVISION_MANAGED_DEVICE";
 
     /**
+     * Activity action: Starts the provisioning flow which sets up a managed device.
+     * Must be started with {@link android.app.Activity#startActivityForResult(Intent, int)}.
+     *
+     * <p>NOTE: This is only supported on split system user devices, and puts the device into a
+     * management state that is distinct from that reached by
+     * {@link #ACTION_PROVISION_MANAGED_DEVICE} - specifically the device owner runs on the system
+     * user, and only has control over device-wide policies, not individual users and their data.
+     * The primary benefit is that multiple non-system users are supported when provisioning using
+     * this form of device management.
+     *
+     * <p> During device owner provisioning a device admin app is set as the owner of the device.
+     * A device owner has full control over the device. The device owner can not be modified by the
+     * user.
+     *
+     * <p> A typical use case would be a device that is owned by a company, but used by either an
+     * employee or client.
+     *
+     * <p> An intent with this action can be sent only on an unprovisioned device.
+     * It is possible to check if provisioning is allowed or not by querying the method
+     * {@link #isProvisioningAllowed(String)}.
+     *
+     * <p>The intent contains the following extras:
+     * <ul>
+     * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
+     * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
+     * </ul>
+     *
+     * <p> When device owner provisioning has completed, an intent of the type
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcast to the
+     * device owner.
+     *
+     * <p> If provisioning fails, the device is factory reset.
+     *
+     * <p>A result code of {@link android.app.Activity#RESULT_OK} implies that the synchronous part
+     * of the provisioning flow was successful, although this doesn't guarantee the full flow will
+     * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies
+     * that the user backed-out of provisioning, or some precondition for provisioning wasn't met.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE
+        = "android.app.action.PROVISION_MANAGED_SHAREABLE_DEVICE";
+
+    /**
      * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
      * allows a mobile device management application or NFC programmer application which starts
      * managed provisioning to pass data to the management application instance after provisioning.
@@ -1636,7 +1711,16 @@
      * Force a new device unlock password (the password needed to access the
      * entire device, not for individual accounts) on the user.  This takes
      * effect immediately.
-     * The given password must be sufficient for the
+     *
+     * <p>Calling this from a managed profile that shares the password with the owner profile
+     * will throw a security exception.
+     *
+     * <p><em>Note: This API has been limited as of {@link android.os.Build.VERSION_CODES#N} for
+     * device admins that are not device owner and not profile owner.
+     * The password can now only be changed if there is currently no password set.  Device owner
+     * and profile owner can still do this.</em>
+     *
+     * <p>The given password must be sufficient for the
      * current password quality and length constraints as returned by
      * {@link #getPasswordQuality(ComponentName)} and
      * {@link #getPasswordMinimumLength(ComponentName)}; if it does not meet
@@ -1646,19 +1730,20 @@
      * the currently active quality will be increased to match.
      *
      * <p>Calling with a null or empty password will clear any existing PIN,
-     * pattern or password if the current password constraints allow it.
+     * pattern or password if the current password constraints allow it. <em>Note: This will not
+     * work in {@link android.os.Build.VERSION_CODES#N} and later for device admins that are not
+     * device owner and not profile owner.  Once set, the password cannot be changed to null or
+     * empty, except by device owner or profile owner.</em>
      *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call
      * this method; if it has not, a security exception will be thrown.
      *
-     * <p>Calling this from a managed profile will throw a security exception.
-     *
      * @param password The new password for the user. Null or empty clears the password.
      * @param flags May be 0 or combination of {@link #RESET_PASSWORD_REQUIRE_ENTRY} and
      *              {@link #RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}.
      * @return Returns true if the password was applied, or false if it is
-     * not acceptable for the current constraints.
+     * not acceptable for the current constraints or if the user has not been decrypted yet.
      */
     public boolean resetPassword(String password, int flags) {
         if (mService != null) {
@@ -1766,7 +1851,7 @@
     public void wipeData(int flags) {
         if (mService != null) {
             try {
-                mService.wipeData(flags, myUserId());
+                mService.wipeData(flags);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -2642,14 +2727,14 @@
      * does *not* check weather the device owner is actually running on the current user.
      */
     public boolean isDeviceOwnerApp(String packageName) {
-        if (mService != null) {
-            try {
-                return mService.isDeviceOwnerPackage(packageName);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
-            }
+        if (packageName == null) {
+            return false;
         }
-        return false;
+        final ComponentName deviceOwner = getDeviceOwnerComponent();
+        if (deviceOwner == null) {
+            return false;
+        }
+        return packageName.equals(deviceOwner.getPackageName());
     }
 
     /**
@@ -2843,9 +2928,6 @@
      */
     public boolean setProfileOwner(@NonNull ComponentName admin, @Deprecated String ownerName,
             int userHandle) throws IllegalArgumentException {
-        if (admin == null) {
-            throw new NullPointerException("admin cannot be null");
-        }
         if (mService != null) {
             try {
                 if (ownerName == null) {
@@ -2861,6 +2943,42 @@
     }
 
     /**
+     * Sets the device owner information to be shown on the lock screen.
+     *
+     * <p>If the device owner information is {@code null} or empty then the device owner info is
+     * cleared and the user owner info is shown on the lock screen if it is set.
+     *
+     * @param admin The name of the admin component to check.
+     * @param info Device owner information which will be displayed instead of the user
+     * owner info.
+     * @return Whether the device owner information has been set.
+     */
+    public boolean setDeviceOwnerLockScreenInfo(@NonNull ComponentName admin, String info) {
+        if (mService != null) {
+            try {
+                return mService.setDeviceOwnerLockScreenInfo(admin, info);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return The device owner information. If it is not set returns {@code null}.
+     */
+    public String getDeviceOwnerLockScreenInfo() {
+        if (mService != null) {
+            try {
+                return mService.getDeviceOwnerLockScreenInfo();
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
+            }
+        }
+        return null;
+    }
+
+    /**
      * Sets the enabled state of the profile. A profile should be enabled only once it is ready to
      * be used. Only the profile owner can call this.
      *
@@ -3637,6 +3755,28 @@
     }
 
     /**
+     * Called by a profile or device owner to get user restrictions set with
+     * {@link #addUserRestriction(ComponentName, String)}.
+     * <p>
+     * The target user may have more restrictions set by the system or other device owner / profile
+     * owner.  To get all the user restrictions currently set, use
+     * {@link UserManager#getUserRestrictions()}.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     */
+    public Bundle getUserRestrictions(@NonNull ComponentName admin) {
+        Bundle ret = null;
+        if (mService != null) {
+            try {
+                ret = mService.getUserRestrictions(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return ret == null ? new Bundle() : ret;
+    }
+
+    /**
      * Called by profile or device owners to hide or unhide packages. When a package is hidden it
      * is unavailable for use, but the data and actual package file remain.
      *
@@ -4299,4 +4439,23 @@
             return PERMISSION_GRANT_STATE_DEFAULT;
         }
     }
+
+    /**
+     * Returns if provisioning a managed profile or device is possible or not.
+     * @param action One of {@link #ACTION_PROVISION_MANAGED_DEVICE},
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE}.
+     * Note that even if this method returns true, there is a slight possibility that the
+     * provisioning will not be allowed when it is actually initiated because some event has
+     * happened in between.
+     * @return if provisioning a managed profile or device is possible or not.
+     * @throws IllegalArgumentException if the supplied action is not valid.
+     */
+    public boolean isProvisioningAllowed(String action) {
+        try {
+            return mService.isProvisioningAllowed(action);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Failed talking with device policy service", re);
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index ccaa8cb..7601cf2 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -81,7 +81,7 @@
 
     void lockNow();
 
-    void wipeData(int flags, int userHandle);
+    void wipeData(int flags);
 
     ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList);
     ComponentName getGlobalProxyAdmin(int userHandle);
@@ -114,7 +114,6 @@
     void reportSuccessfulPasswordAttempt(int userHandle);
 
     boolean setDeviceOwner(in ComponentName who, String ownerName, int userId);
-    boolean isDeviceOwnerPackage(String packageName);
     ComponentName getDeviceOwner();
     String getDeviceOwnerName();
     void clearDeviceOwner(String packageName);
@@ -127,6 +126,9 @@
     void clearProfileOwner(in ComponentName who);
     boolean hasUserSetupCompleted();
 
+    boolean setDeviceOwnerLockScreenInfo(in ComponentName who, String deviceOwnerInfo);
+    String getDeviceOwnerLockScreenInfo();
+
     boolean installCaCert(in ComponentName admin, in byte[] certBuffer);
     void uninstallCaCerts(in ComponentName admin, in String[] aliases);
     void enforceCanManageCaCerts(in ComponentName admin);
@@ -147,6 +149,7 @@
     ComponentName getRestrictionsProvider(int userHandle);
 
     void setUserRestriction(in ComponentName who, in String key, boolean enable);
+    Bundle getUserRestrictions(in ComponentName who);
     void addCrossProfileIntentFilter(in ComponentName admin, in IntentFilter filter, int flags);
     void clearCrossProfileIntentFilters(in ComponentName admin);
 
@@ -227,4 +230,5 @@
     boolean setPermissionGrantState(in ComponentName admin, String packageName,
             String permission, int grantState);
     int getPermissionGrantState(in ComponentName admin, String packageName, String permission);
+    boolean isProvisioningAllowed(String action);
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3f02f17..a0102b6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -724,6 +724,27 @@
     public abstract File getFilesDir();
 
     /**
+     * Return the filesystem directory for storing device-encrypted private app
+     * data. Files stored in this location are typically encrypted with a key
+     * tied to the physical device, and they can be accessed whenever the device
+     * has booted successfully, both <em>before and after</em> the user has
+     * entered their credentials (such as a lock pattern or PIN).
+     */
+    public abstract File getDeviceEncryptedFilesDir();
+
+    /**
+     * Return the filesystem directory for storing credential-encrypted private
+     * app data. Files stored in this location are typically encrypted with a
+     * key tied to user credentials, and they can be accessed
+     * <em>only after</em> the user has entered their credentials (such as a
+     * lock pattern or PIN).
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract File getCredentialEncryptedFilesDir();
+
+    /**
      * Returns the absolute path to the directory on the filesystem similar to
      * {@link #getFilesDir()}. The difference is that files placed under this
      * directory will be excluded from automatic backup to remote storage. See
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 8359edf..bec1b37 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -204,6 +204,18 @@
     }
 
     @Override
+    public File getDeviceEncryptedFilesDir() {
+        return mBase.getDeviceEncryptedFilesDir();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public File getCredentialEncryptedFilesDir() {
+        return mBase.getCredentialEncryptedFilesDir();
+    }
+
+    @Override
     public File getNoBackupFilesDir() {
         return mBase.getNoBackupFilesDir();
     }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 68b77fe..30fe531 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -18,6 +18,7 @@
 
 import android.content.pm.ApplicationInfo;
 import android.os.ResultReceiver;
+import android.os.ShellCommand;
 import android.provider.MediaStore;
 import android.util.ArraySet;
 
@@ -57,11 +58,13 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.Serializable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
@@ -3054,21 +3057,21 @@
 
     /**
      * Thermal state when the device is normal. This state is sent in the
-     * {@link ACTION_THERMAL_EVENT} broadcast as {@link EXTRA_THERMAL_STATE}.
+     * {@link #ACTION_THERMAL_EVENT} broadcast as {@link #EXTRA_THERMAL_STATE}.
      * {@hide}
      */
     public static final int EXTRA_THERMAL_STATE_NORMAL = 0;
 
     /**
      * Thermal state where the device is approaching its maximum threshold. This state is sent in
-     * the {@link ACTION_THERMAL_EVENT} broadcast as {@link EXTRA_THERMAL_STATE}.
+     * the {@link #ACTION_THERMAL_EVENT} broadcast as {@link #EXTRA_THERMAL_STATE}.
      * {@hide}
      */
     public static final int EXTRA_THERMAL_STATE_WARNING = 1;
 
     /**
      * Thermal state where the device has reached its maximum threshold. This state is sent in the
-     * {@link ACTION_THERMAL_EVENT} broadcast as {@link EXTRA_THERMAL_STATE}.
+     * {@link #ACTION_THERMAL_EVENT} broadcast as {@link #EXTRA_THERMAL_STATE}.
      * {@hide}
      */
     public static final int EXTRA_THERMAL_STATE_EXCEEDED = 2;
@@ -5083,6 +5086,437 @@
         return intent;
     }
 
+    /** @hide */
+    public interface CommandOptionHandler {
+        boolean handleOption(String opt, ShellCommand cmd);
+    }
+
+    /** @hide */
+    public static Intent parseCommandArgs(ShellCommand cmd, CommandOptionHandler optionHandler)
+            throws URISyntaxException {
+        Intent intent = new Intent();
+        Intent baseIntent = intent;
+        boolean hasIntentInfo = false;
+
+        Uri data = null;
+        String type = null;
+
+        String opt;
+        while ((opt=cmd.getNextOption()) != null) {
+            switch (opt) {
+                case "-a":
+                    intent.setAction(cmd.getNextArgRequired());
+                    if (intent == baseIntent) {
+                        hasIntentInfo = true;
+                    }
+                    break;
+                case "-d":
+                    data = Uri.parse(cmd.getNextArgRequired());
+                    if (intent == baseIntent) {
+                        hasIntentInfo = true;
+                    }
+                    break;
+                case "-t":
+                    type = cmd.getNextArgRequired();
+                    if (intent == baseIntent) {
+                        hasIntentInfo = true;
+                    }
+                    break;
+                case "-c":
+                    intent.addCategory(cmd.getNextArgRequired());
+                    if (intent == baseIntent) {
+                        hasIntentInfo = true;
+                    }
+                    break;
+                case "-e":
+                case "--es": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    intent.putExtra(key, value);
+                }
+                break;
+                case "--esn": {
+                    String key = cmd.getNextArgRequired();
+                    intent.putExtra(key, (String) null);
+                }
+                break;
+                case "--ei": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    intent.putExtra(key, Integer.decode(value));
+                }
+                break;
+                case "--eu": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    intent.putExtra(key, Uri.parse(value));
+                }
+                break;
+                case "--ecn": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    ComponentName cn = ComponentName.unflattenFromString(value);
+                    if (cn == null)
+                        throw new IllegalArgumentException("Bad component name: " + value);
+                    intent.putExtra(key, cn);
+                }
+                break;
+                case "--eia": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    String[] strings = value.split(",");
+                    int[] list = new int[strings.length];
+                    for (int i = 0; i < strings.length; i++) {
+                        list[i] = Integer.decode(strings[i]);
+                    }
+                    intent.putExtra(key, list);
+                }
+                break;
+                case "--eial": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    String[] strings = value.split(",");
+                    ArrayList<Integer> list = new ArrayList<>(strings.length);
+                    for (int i = 0; i < strings.length; i++) {
+                        list.add(Integer.decode(strings[i]));
+                    }
+                    intent.putExtra(key, list);
+                }
+                break;
+                case "--el": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    intent.putExtra(key, Long.valueOf(value));
+                }
+                break;
+                case "--ela": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    String[] strings = value.split(",");
+                    long[] list = new long[strings.length];
+                    for (int i = 0; i < strings.length; i++) {
+                        list[i] = Long.valueOf(strings[i]);
+                    }
+                    intent.putExtra(key, list);
+                    hasIntentInfo = true;
+                }
+                break;
+                case "--elal": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    String[] strings = value.split(",");
+                    ArrayList<Long> list = new ArrayList<>(strings.length);
+                    for (int i = 0; i < strings.length; i++) {
+                        list.add(Long.valueOf(strings[i]));
+                    }
+                    intent.putExtra(key, list);
+                    hasIntentInfo = true;
+                }
+                break;
+                case "--ef": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    intent.putExtra(key, Float.valueOf(value));
+                    hasIntentInfo = true;
+                }
+                break;
+                case "--efa": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    String[] strings = value.split(",");
+                    float[] list = new float[strings.length];
+                    for (int i = 0; i < strings.length; i++) {
+                        list[i] = Float.valueOf(strings[i]);
+                    }
+                    intent.putExtra(key, list);
+                    hasIntentInfo = true;
+                }
+                break;
+                case "--efal": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    String[] strings = value.split(",");
+                    ArrayList<Float> list = new ArrayList<>(strings.length);
+                    for (int i = 0; i < strings.length; i++) {
+                        list.add(Float.valueOf(strings[i]));
+                    }
+                    intent.putExtra(key, list);
+                    hasIntentInfo = true;
+                }
+                break;
+                case "--esa": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    // Split on commas unless they are preceeded by an escape.
+                    // The escape character must be escaped for the string and
+                    // again for the regex, thus four escape characters become one.
+                    String[] strings = value.split("(?<!\\\\),");
+                    intent.putExtra(key, strings);
+                    hasIntentInfo = true;
+                }
+                break;
+                case "--esal": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired();
+                    // Split on commas unless they are preceeded by an escape.
+                    // The escape character must be escaped for the string and
+                    // again for the regex, thus four escape characters become one.
+                    String[] strings = value.split("(?<!\\\\),");
+                    ArrayList<String> list = new ArrayList<>(strings.length);
+                    for (int i = 0; i < strings.length; i++) {
+                        list.add(strings[i]);
+                    }
+                    intent.putExtra(key, list);
+                    hasIntentInfo = true;
+                }
+                break;
+                case "--ez": {
+                    String key = cmd.getNextArgRequired();
+                    String value = cmd.getNextArgRequired().toLowerCase();
+                    // Boolean.valueOf() results in false for anything that is not "true", which is
+                    // error-prone in shell commands
+                    boolean arg;
+                    if ("true".equals(value) || "t".equals(value)) {
+                        arg = true;
+                    } else if ("false".equals(value) || "f".equals(value)) {
+                        arg = false;
+                    } else {
+                        try {
+                            arg = Integer.decode(value) != 0;
+                        } catch (NumberFormatException ex) {
+                            throw new IllegalArgumentException("Invalid boolean value: " + value);
+                        }
+                    }
+
+                    intent.putExtra(key, arg);
+                }
+                break;
+                case "-n": {
+                    String str = cmd.getNextArgRequired();
+                    ComponentName cn = ComponentName.unflattenFromString(str);
+                    if (cn == null)
+                        throw new IllegalArgumentException("Bad component name: " + str);
+                    intent.setComponent(cn);
+                    if (intent == baseIntent) {
+                        hasIntentInfo = true;
+                    }
+                }
+                break;
+                case "-p": {
+                    String str = cmd.getNextArgRequired();
+                    intent.setPackage(str);
+                    if (intent == baseIntent) {
+                        hasIntentInfo = true;
+                    }
+                }
+                break;
+                case "-f":
+                    String str = cmd.getNextArgRequired();
+                    intent.setFlags(Integer.decode(str).intValue());
+                    break;
+                case "--grant-read-uri-permission":
+                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                    break;
+                case "--grant-write-uri-permission":
+                    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+                    break;
+                case "--grant-persistable-uri-permission":
+                    intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+                    break;
+                case "--grant-prefix-uri-permission":
+                    intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
+                    break;
+                case "--exclude-stopped-packages":
+                    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
+                    break;
+                case "--include-stopped-packages":
+                    intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
+                    break;
+                case "--debug-log-resolution":
+                    intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
+                    break;
+                case "--activity-brought-to-front":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
+                    break;
+                case "--activity-clear-top":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                    break;
+                case "--activity-clear-when-task-reset":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                    break;
+                case "--activity-exclude-from-recents":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                    break;
+                case "--activity-launched-from-history":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
+                    break;
+                case "--activity-multiple-task":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+                    break;
+                case "--activity-no-animation":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+                    break;
+                case "--activity-no-history":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+                    break;
+                case "--activity-no-user-action":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
+                    break;
+                case "--activity-previous-is-top":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+                    break;
+                case "--activity-reorder-to-front":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+                    break;
+                case "--activity-reset-task-if-needed":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+                    break;
+                case "--activity-single-top":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+                    break;
+                case "--activity-clear-task":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+                    break;
+                case "--activity-task-on-home":
+                    intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
+                    break;
+                case "--receiver-registered-only":
+                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    break;
+                case "--receiver-replace-pending":
+                    intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+                    break;
+                case "--selector":
+                    intent.setDataAndType(data, type);
+                    intent = new Intent();
+                    break;
+                default:
+                    if (optionHandler != null && optionHandler.handleOption(opt, cmd)) {
+                        // Okay, caller handled this option.
+                    } else {
+                        throw new IllegalArgumentException("Unknown option: " + opt);
+                    }
+                    break;
+            }
+        }
+        intent.setDataAndType(data, type);
+
+        final boolean hasSelector = intent != baseIntent;
+        if (hasSelector) {
+            // A selector was specified; fix up.
+            baseIntent.setSelector(intent);
+            intent = baseIntent;
+        }
+
+        String arg = cmd.getNextArg();
+        baseIntent = null;
+        if (arg == null) {
+            if (hasSelector) {
+                // If a selector has been specified, and no arguments
+                // have been supplied for the main Intent, then we can
+                // assume it is ACTION_MAIN CATEGORY_LAUNCHER; we don't
+                // need to have a component name specified yet, the
+                // selector will take care of that.
+                baseIntent = new Intent(Intent.ACTION_MAIN);
+                baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            }
+        } else if (arg.indexOf(':') >= 0) {
+            // The argument is a URI.  Fully parse it, and use that result
+            // to fill in any data not specified so far.
+            baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME
+                    | Intent.URI_ANDROID_APP_SCHEME | Intent.URI_ALLOW_UNSAFE);
+        } else if (arg.indexOf('/') >= 0) {
+            // The argument is a component name.  Build an Intent to launch
+            // it.
+            baseIntent = new Intent(Intent.ACTION_MAIN);
+            baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            baseIntent.setComponent(ComponentName.unflattenFromString(arg));
+        } else {
+            // Assume the argument is a package name.
+            baseIntent = new Intent(Intent.ACTION_MAIN);
+            baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            baseIntent.setPackage(arg);
+        }
+        if (baseIntent != null) {
+            Bundle extras = intent.getExtras();
+            intent.replaceExtras((Bundle)null);
+            Bundle uriExtras = baseIntent.getExtras();
+            baseIntent.replaceExtras((Bundle)null);
+            if (intent.getAction() != null && baseIntent.getCategories() != null) {
+                HashSet<String> cats = new HashSet<String>(baseIntent.getCategories());
+                for (String c : cats) {
+                    baseIntent.removeCategory(c);
+                }
+            }
+            intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_SELECTOR);
+            if (extras == null) {
+                extras = uriExtras;
+            } else if (uriExtras != null) {
+                uriExtras.putAll(extras);
+                extras = uriExtras;
+            }
+            intent.replaceExtras(extras);
+            hasIntentInfo = true;
+        }
+
+        if (!hasIntentInfo) throw new IllegalArgumentException("No intent supplied");
+        return intent;
+    }
+
+    /** @hide */
+    public static void printIntentArgsHelp(PrintWriter pw, String prefix) {
+        final String[] lines = new String[] {
+                "<INTENT> specifications include these flags and arguments:",
+                "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]",
+                "    [-c <CATEGORY> [-c <CATEGORY>] ...]",
+                "    [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]",
+                "    [--esn <EXTRA_KEY> ...]",
+                "    [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]",
+                "    [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]",
+                "    [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]",
+                "    [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]",
+                "    [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]",
+                "    [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]",
+                "    [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]",
+                "        (mutiple extras passed as Integer[])",
+                "    [--eial <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]",
+                "        (mutiple extras passed as List<Integer>)",
+                "    [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]",
+                "        (mutiple extras passed as Long[])",
+                "    [--elal <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]",
+                "        (mutiple extras passed as List<Long>)",
+                "    [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]",
+                "        (mutiple extras passed as Float[])",
+                "    [--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]",
+                "        (mutiple extras passed as List<Float>)",
+                "    [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]",
+                "        (mutiple extras passed as String[]; to embed a comma into a string,",
+                "         escape it using \"\\,\")",
+                "    [--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]",
+                "        (mutiple extras passed as List<String>; to embed a comma into a string,",
+                "         escape it using \"\\,\")",
+                "    [--grant-read-uri-permission] [--grant-write-uri-permission]",
+                "    [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]",
+                "    [--debug-log-resolution] [--exclude-stopped-packages]",
+                "    [--include-stopped-packages]",
+                "    [--activity-brought-to-front] [--activity-clear-top]",
+                "    [--activity-clear-when-task-reset] [--activity-exclude-from-recents]",
+                "    [--activity-launched-from-history] [--activity-multiple-task]",
+                "    [--activity-no-animation] [--activity-no-history]",
+                "    [--activity-no-user-action] [--activity-previous-is-top]",
+                "    [--activity-reorder-to-front] [--activity-reset-task-if-needed]",
+                "    [--activity-single-top] [--activity-clear-task]",
+                "    [--activity-task-on-home]",
+                "    [--receiver-registered-only] [--receiver-replace-pending]",
+                "    [--selector]",
+                "    [<URI> | <PACKAGE> | <COMPONENT>]"
+        };
+        for (String line : lines) {
+            pw.print(prefix);
+            pw.println(line);
+        }
+    }
+
     /**
      * Retrieve the general action to be performed, such as
      * {@link #ACTION_VIEW}.  The action describes the general way the rest of
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 7ca39cb..885255f 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -292,7 +292,7 @@
     /**
      * @hide Bit in {@link #flags}: If set, this activity may be launched into an
      * owned ActivityContainer such as that within an ActivityView. If not set and
-     * this activity is launched into such a container a SecurityExcception will be
+     * this activity is launched into such a container a SecurityException will be
      * thrown. Set from the {@link android.R.attr#allowEmbedded} attribute.
      */
     public static final int FLAG_ALLOW_EMBEDDED = 0x80000000;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 914945b..eda4136 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -19,8 +19,12 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
+import android.os.Environment;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.Printer;
 
@@ -459,6 +463,30 @@
     public static final int PRIVATE_FLAG_HAS_DOMAIN_URLS = 1<<4;
 
     /**
+     * When set, default data storage directory for given app is pointed at
+     * device-encrypted location.
+     *
+     * @hide
+     */
+    public static final int PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED = 1 << 5;
+
+    /**
+     * When set, assume that all components under the given app are encryption
+     * aware, unless otherwise specified.
+     *
+     * @hide
+     */
+    public static final int PRIVATE_FLAG_ENCRYPTION_AWARE = 1 << 6;
+
+    /**
+     * Value for {@link #privateFlags}: set to {@code true} if the application
+     * is AutoPlay.
+     *
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_AUTOPLAY = 1 << 7;
+
+    /**
      * Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
      * {@hide}
      */
@@ -549,11 +577,15 @@
     public String[] sharedLibraryFiles;
     
     /**
-     * Full path to a directory assigned to the package for its persistent
-     * data.
+     * Full path to a directory assigned to the package for its persistent data.
      */
     public String dataDir;
 
+    /** {@hide} */
+    public String deviceEncryptedDataDir;
+    /** {@hide} */
+    public String credentialEncryptedDataDir;
+
     /**
      * Full path to the directory where native JNI libraries are stored.
      */
@@ -690,6 +722,8 @@
             pw.println(prefix + "seinfo=" + seinfo);
         }
         pw.println(prefix + "dataDir=" + dataDir);
+        pw.println(prefix + "deviceEncryptedDataDir=" + deviceEncryptedDataDir);
+        pw.println(prefix + "credentialEncryptedDataDir=" + credentialEncryptedDataDir);
         if (sharedLibraryFiles != null) {
             pw.println(prefix + "sharedLibraryFiles=" + Arrays.toString(sharedLibraryFiles));
         }
@@ -776,6 +810,8 @@
         seinfo = orig.seinfo;
         sharedLibraryFiles = orig.sharedLibraryFiles;
         dataDir = orig.dataDir;
+        deviceEncryptedDataDir = orig.deviceEncryptedDataDir;
+        credentialEncryptedDataDir = orig.credentialEncryptedDataDir;
         uid = orig.uid;
         targetSdkVersion = orig.targetSdkVersion;
         versionCode = orig.versionCode;
@@ -789,7 +825,6 @@
         fullBackupContent = orig.fullBackupContent;
     }
 
-
     public String toString() {
         return "ApplicationInfo{"
             + Integer.toHexString(System.identityHashCode(this))
@@ -829,6 +864,8 @@
         dest.writeString(seinfo);
         dest.writeStringArray(sharedLibraryFiles);
         dest.writeString(dataDir);
+        dest.writeString(deviceEncryptedDataDir);
+        dest.writeString(credentialEncryptedDataDir);
         dest.writeInt(uid);
         dest.writeInt(targetSdkVersion);
         dest.writeInt(versionCode);
@@ -881,6 +918,8 @@
         seinfo = source.readString();
         sharedLibraryFiles = source.readStringArray();
         dataDir = source.readString();
+        deviceEncryptedDataDir = source.readString();
+        credentialEncryptedDataDir = source.readString();
         uid = source.readInt();
         targetSdkVersion = source.readInt();
         versionCode = source.readInt();
@@ -925,7 +964,31 @@
                 FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS |
                 FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
     }
-    
+
+    /** {@hide} */
+    public void initForUser(int userId) {
+        uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
+
+        if ("android".equals(packageName)) {
+            dataDir = Environment.getDataSystemDirectory().getAbsolutePath();
+            return;
+        }
+
+        deviceEncryptedDataDir = Environment
+                .getDataUserDeviceEncryptedPackageDirectory(volumeUuid, userId, packageName)
+                .getAbsolutePath();
+        credentialEncryptedDataDir = Environment
+                .getDataUserCredentialEncryptedPackageDirectory(volumeUuid, userId, packageName)
+                .getAbsolutePath();
+
+        if ((privateFlags & PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0
+                && SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false)) {
+            dataDir = deviceEncryptedDataDir;
+        } else {
+            dataDir = credentialEncryptedDataDir;
+        }
+    }
+
     /**
      * @hide
      */
@@ -986,6 +1049,18 @@
                 && (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
     }
 
+    /** @hide */
+    public boolean isEncryptionAware() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_ENCRYPTION_AWARE) != 0;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isAutoPlayApp() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_AUTOPLAY) != 0;
+    }
+
     /**
      * @hide
      */
diff --git a/core/java/android/content/pm/AppsQueryHelper.java b/core/java/android/content/pm/AppsQueryHelper.java
index a5a8e3f..084bc18 100644
--- a/core/java/android/content/pm/AppsQueryHelper.java
+++ b/core/java/android/content/pm/AppsQueryHelper.java
@@ -18,13 +18,11 @@
 
 import android.Manifest;
 import android.app.AppGlobals;
-import android.content.Context;
 import android.content.Intent;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.ArraySet;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethod;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -44,36 +42,37 @@
     public static int GET_NON_LAUNCHABLE_APPS = 1;
 
     /**
-     * Return apps with {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission
+     * Return apps with {@link Manifest.permission#INTERACT_ACROSS_USERS} permission
      */
     public static int GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM = 1 << 1;
 
     /**
-     * Return all input methods that are marked as default.
-     * <p>When this flag is set, {@code user} specified in
-     * {@link #queryApps(int, boolean, UserHandle)} must be
-     * {@link UserHandle#myUserId user of the current process}.
+     * Return all input methods available for the current user.
      */
-    public static int GET_DEFAULT_IMES = 1 << 2;
+    public static int GET_IMES = 1 << 2;
 
-    private final Context mContext;
+    private final IPackageManager mPackageManager;
     private List<ApplicationInfo> mAllApps;
 
-    public AppsQueryHelper(Context context) {
-        mContext = context;
+    public AppsQueryHelper(IPackageManager packageManager) {
+        mPackageManager = packageManager;
+    }
+
+    public AppsQueryHelper() {
+        this(AppGlobals.getPackageManager());
     }
 
     /**
      * Return a List of all packages that satisfy a specified criteria.
      * @param flags search flags. Use any combination of {@link #GET_NON_LAUNCHABLE_APPS},
-     * {@link #GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM} or {@link #GET_DEFAULT_IMES}.
+     * {@link #GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM} or {@link #GET_IMES}.
      * @param systemAppsOnly if true, only system apps will be returned
      * @param user user, whose apps are queried
      */
     public List<String> queryApps(int flags, boolean systemAppsOnly, UserHandle user) {
         boolean nonLaunchableApps = (flags & GET_NON_LAUNCHABLE_APPS) > 0;
         boolean interactAcrossUsers = (flags & GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM) > 0;
-        boolean defaultImes = (flags & GET_DEFAULT_IMES) > 0;
+        boolean imes = (flags & GET_IMES) > 0;
         if (mAllApps == null) {
             mAllApps = getAllApps(user.getIdentifier());
         }
@@ -113,7 +112,6 @@
                 }
             }
         }
-
         if (interactAcrossUsers) {
             final List<PackageInfo> packagesHoldingPermissions = getPackagesHoldingPermission(
                     Manifest.permission.INTERACT_ACROSS_USERS, user.getIdentifier());
@@ -129,29 +127,18 @@
             }
         }
 
-        if (defaultImes) {
-            if (UserHandle.myUserId() != user.getIdentifier()) {
-                throw new IllegalArgumentException("Specified user handle " + user
-                        + " is not a user of the current process.");
-            }
-            List<InputMethodInfo> imis = getInputMethodList();
-            int imisSize = imis.size();
-            ArraySet<String> defaultImePackages = new ArraySet<>();
-            for (int i = 0; i < imisSize; i++) {
-                InputMethodInfo imi = imis.get(i);
-                if (imi.isDefault(mContext)) {
-                    defaultImePackages.add(imi.getPackageName());
-                }
-            }
-            final int allAppsSize = mAllApps.size();
-            for (int i = 0; i < allAppsSize; i++) {
-                final ApplicationInfo appInfo = mAllApps.get(i);
-                if (systemAppsOnly && !appInfo.isSystemApp()) {
+        if (imes) {
+            final List<ResolveInfo> resolveInfos = queryIntentServicesAsUser(
+                    new Intent(InputMethod.SERVICE_INTERFACE), user.getIdentifier());
+            final int resolveInfosSize = resolveInfos.size();
+
+            for (int i = 0; i < resolveInfosSize; i++) {
+                ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo;
+                if (systemAppsOnly && !serviceInfo.applicationInfo.isSystemApp()) {
                     continue;
                 }
-                final String packageName = appInfo.packageName;
-                if (defaultImePackages.contains(packageName)) {
-                    result.add(packageName);
+                if (!result.contains(serviceInfo.packageName)) {
+                    result.add(serviceInfo.packageName);
                 }
             }
         }
@@ -163,9 +150,8 @@
     @SuppressWarnings("unchecked")
     protected List<ApplicationInfo> getAllApps(int userId) {
         try {
-            return AppGlobals.getPackageManager().getInstalledApplications(
-                    PackageManager.GET_UNINSTALLED_PACKAGES
-                            | PackageManager.GET_DISABLED_COMPONENTS, userId).getList();
+            return mPackageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES
+                    | PackageManager.GET_DISABLED_COMPONENTS, userId).getList();
         } catch (RemoteException e) {
             throw new IllegalStateException("Package manager has died", e);
         }
@@ -173,17 +159,22 @@
 
     @VisibleForTesting
     protected List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int userId) {
-        return mContext.getPackageManager()
-                .queryIntentActivitiesAsUser(intent, PackageManager.GET_DISABLED_COMPONENTS
-                        | PackageManager.GET_UNINSTALLED_PACKAGES, userId);
+        try {
+            return mPackageManager.queryIntentActivities(intent, null,
+                    PackageManager.GET_DISABLED_COMPONENTS
+                            | PackageManager.GET_UNINSTALLED_PACKAGES,
+                    userId);
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Package manager has died", e);
+        }
     }
 
     @VisibleForTesting
-    @SuppressWarnings("unchecked")
-    protected List<PackageInfo> getPackagesHoldingPermission(String perm, int userId) {
+    protected List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int userId) {
         try {
-            return AppGlobals.getPackageManager().getPackagesHoldingPermissions(new String[]{perm},
-                    0, userId).getList();
+            return mPackageManager.queryIntentServices(intent, null,
+                    PackageManager.GET_META_DATA
+                            | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, userId);
         } catch (RemoteException e) {
             throw new IllegalStateException("Package manager has died", e);
         }
@@ -191,9 +182,13 @@
 
     @VisibleForTesting
     @SuppressWarnings("unchecked")
-    protected List<InputMethodInfo> getInputMethodList() {
-        InputMethodManager imm = (InputMethodManager)
-                mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
-        return imm.getInputMethodList();
+    protected List<PackageInfo> getPackagesHoldingPermission(String perm, int userId) {
+        try {
+            return mPackageManager.getPackagesHoldingPermissions(new String[]{perm}, 0,
+                    userId).getList();
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Package manager has died", e);
+        }
     }
+
 }
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index f27fc2a..ad7ebe5 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -63,7 +63,14 @@
      * &lt;provider&gt; tag.
      */
     public boolean exported = false;
-    
+
+    /**
+     * Indicate if this component is aware of encryption lifecycle, and can be
+     * safely run before the user has entered their credentials (such as a lock
+     * pattern or PIN).
+     */
+    public boolean encryptionAware = false;
+
     public ComponentInfo() {
     }
 
@@ -74,6 +81,7 @@
         descriptionRes = orig.descriptionRes;
         enabled = orig.enabled;
         exported = orig.exported;
+        encryptionAware = orig.encryptionAware;
     }
 
     @Override public CharSequence loadLabel(PackageManager pm) {
@@ -143,7 +151,7 @@
     protected void dumpFront(Printer pw, String prefix) {
         super.dumpFront(pw, prefix);
         pw.println(prefix + "enabled=" + enabled + " exported=" + exported
-                + " processName=" + processName);
+                + " encryptionAware=" + encryptionAware + " processName=" + processName);
         if (descriptionRes != 0) {
             pw.println(prefix + "description=" + descriptionRes);
         }
@@ -171,6 +179,7 @@
         dest.writeInt(descriptionRes);
         dest.writeInt(enabled ? 1 : 0);
         dest.writeInt(exported ? 1 : 0);
+        dest.writeInt(encryptionAware ? 1 : 0);
     }
     
     protected ComponentInfo(Parcel source) {
@@ -183,6 +192,7 @@
         descriptionRes = source.readInt();
         enabled = (source.readInt() != 0);
         exported = (source.readInt() != 0);
+        encryptionAware = (source.readInt() != 0);
     }
     
     /**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index fec2c44..6fe1efd 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -420,10 +420,14 @@
     boolean hasSystemUidErrors();
 
     /**
-     * Ask the package manager to perform boot-time dex-opt of all
-     * existing packages.
+     * Ask the package manager to fstrim the disk if needed.
      */
-    void performBootDexOpt();
+    void performFstrimIfNeeded();
+
+    /**
+     * Notify the package manager that a package is going to be used.
+     */
+    void notifyPackageUse(String packageName);
 
     /**
      * Ask the package manager to perform dex-opt (if needed) on the given
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
index dab0caf..44bdf4e 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -57,11 +57,15 @@
     public String[] splitPublicSourceDirs;
 
     /**
-     * Full path to a directory assigned to the package for its persistent
-     * data.
+     * Full path to a directory assigned to the package for its persistent data.
      */
     public String dataDir;
 
+    /** {@hide} */
+    public String deviceEncryptedDataDir;
+    /** {@hide} */
+    public String credentialEncryptedDataDir;
+
     /**
      * Full path to the directory where the native JNI libraries are stored.
      * 
@@ -85,7 +89,11 @@
         targetPackage = orig.targetPackage;
         sourceDir = orig.sourceDir;
         publicSourceDir = orig.publicSourceDir;
+        splitSourceDirs = orig.splitSourceDirs;
+        splitPublicSourceDirs = orig.splitPublicSourceDirs;
         dataDir = orig.dataDir;
+        deviceEncryptedDataDir = orig.deviceEncryptedDataDir;
+        credentialEncryptedDataDir = orig.credentialEncryptedDataDir;
         nativeLibraryDir = orig.nativeLibraryDir;
         handleProfiling = orig.handleProfiling;
         functionalTest = orig.functionalTest;
@@ -106,7 +114,11 @@
         dest.writeString(targetPackage);
         dest.writeString(sourceDir);
         dest.writeString(publicSourceDir);
+        dest.writeStringArray(splitSourceDirs);
+        dest.writeStringArray(splitPublicSourceDirs);
         dest.writeString(dataDir);
+        dest.writeString(deviceEncryptedDataDir);
+        dest.writeString(credentialEncryptedDataDir);
         dest.writeString(nativeLibraryDir);
         dest.writeInt((handleProfiling == false) ? 0 : 1);
         dest.writeInt((functionalTest == false) ? 0 : 1);
@@ -127,9 +139,26 @@
         targetPackage = source.readString();
         sourceDir = source.readString();
         publicSourceDir = source.readString();
+        splitSourceDirs = source.readStringArray();
+        splitPublicSourceDirs = source.readStringArray();
         dataDir = source.readString();
+        deviceEncryptedDataDir = source.readString();
+        credentialEncryptedDataDir = source.readString();
         nativeLibraryDir = source.readString();
         handleProfiling = source.readInt() != 0;
         functionalTest = source.readInt() != 0;
     }
+
+    /** {@hide} */
+    public void copyTo(ApplicationInfo ai) {
+        ai.packageName = packageName;
+        ai.sourceDir = sourceDir;
+        ai.publicSourceDir = publicSourceDir;
+        ai.splitSourceDirs = splitSourceDirs;
+        ai.splitPublicSourceDirs = splitPublicSourceDirs;
+        ai.dataDir = dataDir;
+        ai.deviceEncryptedDataDir = deviceEncryptedDataDir;
+        ai.credentialEncryptedDataDir = credentialEncryptedDataDir;
+        ai.nativeLibraryDir = nativeLibraryDir;
+    }
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c57fc89..566de4e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -234,6 +234,24 @@
     public static final int MATCH_ALL = 0x00020000;
 
     /**
+     * {@link PackageInfo} flag: include components which aren't encryption
+     * aware in the returned info, regardless of the current user state.
+     */
+    public static final int GET_ENCRYPTION_UNAWARE_COMPONENTS = 0x00040000;
+
+    /**
+     * {@link PackageInfo} flag: return components as if the given user is
+     * running with amnesia. This typically limits the component to only those
+     * marked as {@link ComponentInfo#encryptionAware}, unless
+     * {@link #GET_ENCRYPTION_UNAWARE_COMPONENTS} is also specified.
+     * <p>
+     * This flag is for internal use only.
+     *
+     * @hide
+     */
+    public static final int FLAG_USER_RUNNING_WITH_AMNESIA = 0x00080000;
+
+    /**
      * Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
      * when resolving an intent that matches the {@link CrossProfileIntentFilter}, the current
      * profile will be skipped.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 5d73b06..838da37 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2632,6 +2632,15 @@
             ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
         }
 
+        if (sa.getBoolean(R.styleable.AndroidManifestApplication_forceDeviceEncrypted, false)
+                && (flags & PARSE_IS_SYSTEM) != 0) {
+            ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED;
+        }
+        if (sa.getBoolean(R.styleable.AndroidManifestApplication_encryptionAware, false)
+                && (flags & PARSE_IS_SYSTEM) != 0) {
+            ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ENCRYPTION_AWARE;
+        }
+
         String str;
         str = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
@@ -3229,6 +3238,10 @@
 
             a.info.lockTaskLaunchMode =
                     sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
+
+            a.info.encryptionAware = sa.getBoolean(
+                    R.styleable.AndroidManifestActivity_encryptionAware,
+                    owner.applicationInfo.isEncryptionAware());
         } else {
             a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
             a.info.configChanges = 0;
@@ -3243,6 +3256,10 @@
                     setExported = true;
                 }
             }
+
+            a.info.encryptionAware = sa.getBoolean(
+                    R.styleable.AndroidManifestActivity_encryptionAware,
+                    owner.applicationInfo.isEncryptionAware());
         }
 
         sa.recycle();
@@ -3643,6 +3660,10 @@
             }
         }
 
+        p.info.encryptionAware = sa.getBoolean(
+                R.styleable.AndroidManifestProvider_encryptionAware,
+                owner.applicationInfo.isEncryptionAware());
+
         sa.recycle();
 
         if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
@@ -3923,6 +3944,10 @@
             }
         }
 
+        s.info.encryptionAware = sa.getBoolean(
+                R.styleable.AndroidManifestService_encryptionAware,
+                owner.applicationInfo.isEncryptionAware());
+
         sa.recycle();
 
         if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
@@ -4875,9 +4900,7 @@
 
         // Make shallow copy so we can store the metadata/libraries safely
         ApplicationInfo ai = new ApplicationInfo(p.applicationInfo);
-        ai.uid = UserHandle.getUid(userId, ai.uid);
-        ai.dataDir = Environment.getDataUserPackageDirectory(ai.volumeUuid, userId, ai.packageName)
-                .getAbsolutePath();
+        ai.initForUser(userId);
         if ((flags & PackageManager.GET_META_DATA) != 0) {
             ai.metaData = p.mAppMetaData;
         }
@@ -4902,9 +4925,7 @@
         // This is only used to return the ResolverActivity; we will just always
         // make a copy.
         ai = new ApplicationInfo(ai);
-        ai.uid = UserHandle.getUid(userId, ai.uid);
-        ai.dataDir = Environment.getDataUserPackageDirectory(ai.volumeUuid, userId, ai.packageName)
-                .getAbsolutePath();
+        ai.initForUser(userId);
         if (state.stopped) {
             ai.flags |= ApplicationInfo.FLAG_STOPPED;
         } else {
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 04c690b..7669053 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -686,13 +686,6 @@
     public native final boolean isUpToDate();
 
     /**
-     * Change the locale being used by this asset manager.  Not for use by
-     * applications.
-     * {@hide}
-     */
-    public native final void setLocale(String locale);
-
-    /**
      * Get the locales that this asset manager contains data for.
      *
      * <p>On SDK 21 (Android 5.0: Lollipop) and above, Locale strings are valid
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 477b62c..1a19a58 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1505,21 +1505,27 @@
      *
      * @hide
      */
-    public static String localeToResourceQualifier(Locale loc) {
+    public static String localesToResourceQualifier(LocaleList locs) {
         StringBuilder sb = new StringBuilder();
-        boolean l = (loc.getLanguage().length() != 0);
-        boolean c = (loc.getCountry().length() != 0);
-        boolean s = (loc.getScript().length() != 0);
-        boolean v = (loc.getVariant().length() != 0);
-        // TODO: take script and extensions into account
-        if (l) {
-            sb.append(loc.getLanguage());
-            if (c) {
-                sb.append("-r").append(loc.getCountry());
-                if (s) {
-                    sb.append("-s").append(loc.getScript());
-                    if (v) {
-                        sb.append("-v").append(loc.getVariant());
+        for (int i = 0; i < locs.size(); i++) {
+            Locale loc = locs.get(i);
+            boolean l = (loc.getLanguage().length() != 0);
+            boolean c = (loc.getCountry().length() != 0);
+            boolean s = (loc.getScript().length() != 0);
+            boolean v = (loc.getVariant().length() != 0);
+            // TODO: take script and extensions into account
+            if (l) {
+                if (sb.length() != 0) {
+                    sb.append(",");
+                }
+                sb.append(loc.getLanguage());
+                if (c) {
+                    sb.append("-r").append(loc.getCountry());
+                    if (s) {
+                        sb.append("-s").append(loc.getScript());
+                        if (v) {
+                            sb.append("-v").append(loc.getVariant());
+                        }
                     }
                 }
             }
@@ -1544,9 +1550,11 @@
             }
         }
 
-        // TODO: send the whole locale list
-        if (config.locale != null && !config.locale.getLanguage().isEmpty()) {
-            parts.add(localeToResourceQualifier(config.locale));
+        if (!config.mLocaleList.isEmpty()) {
+            final String resourceQualifier = localesToResourceQualifier(config.mLocaleList);
+            if (!resourceQualifier.isEmpty()) {
+                parts.add(resourceQualifier);
+            }
         }
 
         switch (config.screenLayout & Configuration.SCREENLAYOUT_LAYOUTDIR_MASK) {
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 0606e35..7b3dde4 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -48,7 +48,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Trace;
-import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.LocaleList;
@@ -68,7 +67,6 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.ref.WeakReference;
 import java.util.Locale;
 
 /**
@@ -120,9 +118,6 @@
     private static final LongSparseArray<android.content.res.ConstantState<ColorStateList>>
             sPreloadedColorStateLists = new LongSparseArray<>();
 
-    private static final String CACHE_NOT_THEMED = "";
-    private static final String CACHE_NULL_THEME = "null_theme";
-
     // Pool of TypedArrays targeted to this Resources object.
     final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<>(5);
 
@@ -130,10 +125,11 @@
     static Resources mSystem = null;
 
     private static boolean sPreloaded;
-    private static int sPreloadedDensity;
+
+    /** Lock object used to protect access to caches and configuration. */
+    private final Object mAccessLock = new Object();
 
     // These are protected by mAccessLock.
-    private final Object mAccessLock = new Object();
     private final Configuration mTmpConfig = new Configuration();
     private final DrawableCache mDrawableCache = new DrawableCache(this);
     private final DrawableCache mColorDrawableCache = new DrawableCache(this);
@@ -147,7 +143,12 @@
     /** Used to inflate drawable objects from XML. */
     private DrawableInflater mDrawableInflater;
 
+    /** Lock object used to protect access to {@link #mTmpValue}. */
+    private final Object mTmpValueLock = new Object();
+
+    /** Single-item pool used to minimize TypedValue allocations. */
     private TypedValue mTmpValue = new TypedValue();
+
     private boolean mPreloading;
 
     private int mLastCachedXmlBlockIndex = -1;
@@ -249,6 +250,10 @@
         public NotFoundException(String name) {
             super(name);
         }
+
+        public NotFoundException(String name, Exception cause) {
+            super(name, cause);
+        }
     }
 
     /**
@@ -621,18 +626,15 @@
      * @see #getDimensionPixelSize
      */
     public float getDimension(@DimenRes int id) throws NotFoundException {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type == TypedValue.TYPE_DIMENSION) {
                 return TypedValue.complexToDimension(value.data, mMetrics);
             }
-            throw new NotFoundException(
-                    "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                    + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
 
@@ -656,19 +658,15 @@
      * @see #getDimensionPixelSize
      */
     public int getDimensionPixelOffset(@DimenRes int id) throws NotFoundException {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type == TypedValue.TYPE_DIMENSION) {
-                return TypedValue.complexToDimensionPixelOffset(
-                        value.data, mMetrics);
+                return TypedValue.complexToDimensionPixelOffset(value.data, mMetrics);
             }
-            throw new NotFoundException(
-                    "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                    + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
 
@@ -693,19 +691,15 @@
      * @see #getDimensionPixelOffset
      */
     public int getDimensionPixelSize(@DimenRes int id) throws NotFoundException {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type == TypedValue.TYPE_DIMENSION) {
-                return TypedValue.complexToDimensionPixelSize(
-                        value.data, mMetrics);
+                return TypedValue.complexToDimensionPixelSize(value.data, mMetrics);
             }
-            throw new NotFoundException(
-                    "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                    + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
 
@@ -727,18 +721,15 @@
      * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
      */
     public float getFraction(@FractionRes int id, int base, int pbase) {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type == TypedValue.TYPE_FRACTION) {
                 return TypedValue.complexToFraction(value.data, base, pbase);
             }
-            throw new NotFoundException(
-                    "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                    + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
     
@@ -801,24 +792,14 @@
      *         not exist.
      */
     @Nullable
-    public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme) throws NotFoundException {
-        TypedValue value;
-        synchronized (mAccessLock) {
-            value = mTmpValue;
-            if (value == null) {
-                value = new TypedValue();
-            } else {
-                mTmpValue = null;
-            }
-            getValue(id, value, true);
+    public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
+            throws NotFoundException {
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
+            return loadDrawable(value, id, theme);
+        } finally {
+            releaseTempTypedValue(value);
         }
-        final Drawable res = loadDrawable(value, id, theme);
-        synchronized (mAccessLock) {
-            if (mTmpValue == null) {
-                mTmpValue = value;
-            }
-        }
-        return res;
     }
 
     /**
@@ -849,7 +830,8 @@
      */
     @Deprecated
     @Nullable
-    public Drawable getDrawableForDensity(@DrawableRes int id, int density) throws NotFoundException {
+    public Drawable getDrawableForDensity(@DrawableRes int id, int density)
+            throws NotFoundException {
         return getDrawableForDensity(id, density, null);
     }
 
@@ -869,14 +851,8 @@
      */
     @Nullable
     public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme) {
-        TypedValue value;
-        synchronized (mAccessLock) {
-            value = mTmpValue;
-            if (value == null) {
-                value = new TypedValue();
-            } else {
-                mTmpValue = null;
-            }
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             getValueForDensity(id, density, value, true);
 
             /*
@@ -893,15 +869,11 @@
                     value.density = (value.density * mMetrics.densityDpi) / density;
                 }
             }
-        }
 
-        final Drawable res = loadDrawable(value, id, theme);
-        synchronized (mAccessLock) {
-            if (mTmpValue == null) {
-                mTmpValue = value;
-            }
+            return loadDrawable(value, id, theme);
+        } finally {
+            releaseTempTypedValue(value);
         }
-        return res;
     }
 
     /**
@@ -963,33 +935,21 @@
      */
     @ColorInt
     public int getColor(@ColorRes int id, @Nullable Theme theme) throws NotFoundException {
-        TypedValue value;
-        synchronized (mAccessLock) {
-            value = mTmpValue;
-            if (value == null) {
-                value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type >= TypedValue.TYPE_FIRST_INT
                     && value.type <= TypedValue.TYPE_LAST_INT) {
-                mTmpValue = value;
                 return value.data;
             } else if (value.type != TypedValue.TYPE_STRING) {
-                throw new NotFoundException(
-                        "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                                + Integer.toHexString(value.type) + " is not valid");
+                throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                        + " type #0x" + Integer.toHexString(value.type) + " is not valid");
             }
-            mTmpValue = null;
-        }
 
-        final ColorStateList csl = loadColorStateList(value, id, theme);
-        synchronized (mAccessLock) {
-            if (mTmpValue == null) {
-                mTmpValue = value;
-            }
+            final ColorStateList csl = loadColorStateList(value, id, theme);
+            return csl.getDefaultColor();
+        } finally {
+            releaseTempTypedValue(value);
         }
-
-        return csl.getDefaultColor();
     }
 
     /**
@@ -1043,25 +1003,12 @@
     @Nullable
     public ColorStateList getColorStateList(@ColorRes int id, @Nullable Theme theme)
             throws NotFoundException {
-        TypedValue value;
-        synchronized (mAccessLock) {
-            value = mTmpValue;
-            if (value == null) {
-                value = new TypedValue();
-            } else {
-                mTmpValue = null;
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
+            return loadColorStateList(value, id, theme);
+        } finally {
+            releaseTempTypedValue(value);
         }
-
-        final ColorStateList res = loadColorStateList(value, id, theme);
-        synchronized (mAccessLock) {
-            if (mTmpValue == null) {
-                mTmpValue = value;
-            }
-        }
-
-        return res;
     }
 
     /**
@@ -1078,19 +1025,16 @@
      * @return Returns the boolean value contained in the resource.
      */
     public boolean getBoolean(@BoolRes int id) throws NotFoundException {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type >= TypedValue.TYPE_FIRST_INT
-                && value.type <= TypedValue.TYPE_LAST_INT) {
+                    && value.type <= TypedValue.TYPE_LAST_INT) {
                 return value.data != 0;
             }
-            throw new NotFoundException(
-                "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
 
@@ -1106,19 +1050,16 @@
      * @return Returns the integer value contained in the resource.
      */
     public int getInteger(@IntegerRes int id) throws NotFoundException {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type >= TypedValue.TYPE_FIRST_INT
-                && value.type <= TypedValue.TYPE_LAST_INT) {
+                    && value.type <= TypedValue.TYPE_LAST_INT) {
                 return value.data;
             }
-            throw new NotFoundException(
-                "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
 
@@ -1136,17 +1077,15 @@
      * @hide Pending API council approval.
      */
     public float getFloat(int id) {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type == TypedValue.TYPE_FLOAT) {
                 return value.getFloat();
             }
-            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                    + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
 
@@ -1238,22 +1177,60 @@
      * 
      */
     public InputStream openRawResource(@RawRes int id) throws NotFoundException {
-        TypedValue value;
-        synchronized (mAccessLock) {
-            value = mTmpValue;
-            if (value == null) {
-                value = new TypedValue();
-            } else {
+        final TypedValue value = obtainTempTypedValue();
+        try {
+            return openRawResource(id, value);
+        } finally {
+            releaseTempTypedValue(value);
+        }
+    }
+
+    /**
+     * Returns a TypedValue populated with data for the specified resource ID
+     * that's suitable for temporary use. The obtained TypedValue should be
+     * released using {@link #releaseTempTypedValue(TypedValue)}.
+     *
+     * @param id the resource ID for which data should be obtained
+     * @return a populated typed value suitable for temporary use
+     */
+    private TypedValue obtainTempTypedValue(@AnyRes int id) {
+        final TypedValue value = obtainTempTypedValue();
+        getValue(id, value, true);
+        return value;
+    }
+
+    /**
+     * Returns a TypedValue suitable for temporary use. The obtained TypedValue
+     * should be released using {@link #releaseTempTypedValue(TypedValue)}.
+     *
+     * @return a typed value suitable for temporary use
+     */
+    private TypedValue obtainTempTypedValue() {
+        TypedValue tmpValue = null;
+        synchronized (mTmpValueLock) {
+            if (mTmpValue != null) {
+                tmpValue = mTmpValue;
                 mTmpValue = null;
             }
         }
-        InputStream res = openRawResource(id, value);
-        synchronized (mAccessLock) {
+        if (tmpValue == null) {
+            return new TypedValue();
+        }
+        return tmpValue;
+    }
+
+    /**
+     * Returns a TypedValue to the pool. After calling this method, the
+     * specified TypedValue should no longer be accessed.
+     *
+     * @param value the typed value to return to the pool
+     */
+    private void releaseTempTypedValue(TypedValue value) {
+        synchronized (mTmpValueLock) {
             if (mTmpValue == null) {
                 mTmpValue = value;
             }
         }
-        return res;
     }
 
     /**
@@ -1307,32 +1284,14 @@
      */
     public AssetFileDescriptor openRawResourceFd(@RawRes int id)
             throws NotFoundException {
-        TypedValue value;
-        synchronized (mAccessLock) {
-            value = mTmpValue;
-            if (value == null) {
-                value = new TypedValue();
-            } else {
-                mTmpValue = null;
-            }
-            getValue(id, value, true);
-        }
+        final TypedValue value = obtainTempTypedValue(id);
         try {
-            return mAssets.openNonAssetFd(
-                value.assetCookie, value.string.toString());
+            return mAssets.openNonAssetFd(value.assetCookie, value.string.toString());
         } catch (Exception e) {
-            NotFoundException rnf = new NotFoundException(
-                "File " + value.string.toString()
-                + " from drawable resource ID #0x"
-                + Integer.toHexString(id));
-            rnf.initCause(e);
-            throw rnf;
+            throw new NotFoundException("File " + value.string.toString() + " from drawable "
+                    + "resource ID #0x" + Integer.toHexString(id), e);
         } finally {
-            synchronized (mAccessLock) {
-                if (mTmpValue == null) {
-                    mTmpValue = value;
-                }
-            }
+            releaseTempTypedValue(value);
         }
     }
 
@@ -2015,8 +1974,8 @@
                     Build.VERSION.RESOURCES_SDK_INT);
 
             if (DEBUG_CONFIG) {
-                Slog.i(TAG, "**** Updating config of " + this + ": final config is " + mConfiguration
-                        + " final compat is " + mCompatibilityInfo);
+                Slog.i(TAG, "**** Updating config of " + this + ": final config is "
+                        + mConfiguration + " final compat is " + mCompatibilityInfo);
             }
 
             mDrawableCache.onConfigurationChange(configChanges);
@@ -2402,8 +2361,7 @@
             }
             sPreloaded = true;
             mPreloading = true;
-            sPreloadedDensity = DisplayMetrics.DENSITY_DEVICE;
-            mConfiguration.densityDpi = sPreloadedDensity;
+            mConfiguration.densityDpi = DisplayMetrics.DENSITY_DEVICE;
             updateConfiguration(null, null);
         }
     }
@@ -2740,19 +2698,16 @@
 
     /*package*/ XmlResourceParser loadXmlResourceParser(int id, String type)
             throws NotFoundException {
-        synchronized (mAccessLock) {
-            TypedValue value = mTmpValue;
-            if (value == null) {
-                mTmpValue = value = new TypedValue();
-            }
-            getValue(id, value, true);
+        final TypedValue value = obtainTempTypedValue(id);
+        try {
             if (value.type == TypedValue.TYPE_STRING) {
                 return loadXmlResourceParser(value.string.toString(), id,
                         value.assetCookie, type);
             }
-            throw new NotFoundException(
-                    "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
-                    + Integer.toHexString(value.type) + " is not valid");
+            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
+                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
+        } finally {
+            releaseTempTypedValue(value);
         }
     }
     
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 1fc69c0..73bb426 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -3182,8 +3182,8 @@
         }
 
         /**
-         * Sets GPS processing method. It will store up to 32 characters
-         * in JPEG EXIF header.
+         * Sets GPS processing method. The method will be stored in a UTF-8 string up to 31 bytes
+         * long, in the JPEG EXIF header.
          *
          * @param processing_method The processing method to get this location.
          */
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 35a1d96..f61892e 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -472,13 +472,13 @@
      * <li>The maximum available resolution for RAW_SENSOR streams
      *   will match either the value in
      *   {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize} or
-     *   {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</li>
+     *   {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.</li>
      * <li>All DNG-related optional metadata entries are provided
      *   by the camera device.</li>
      * </ul>
      *
-     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 3f566eb..67835a0 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -556,6 +556,10 @@
          * Set a capture request field to a value. The field definitions can be
          * found in {@link CaptureRequest}.
          *
+         * <p>Setting a field to {@code null} will remove that field from the capture request.
+         * Unless the field is optional, removing it will likely produce an error from the camera
+         * device when the request is submitted.</p>
+         *
          * @param key The metadata field to write.
          * @param value The value to set the field to, which must be of a matching
          * type to the key.
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 308a219..6effc0d 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -93,7 +93,8 @@
     public static final int RESULT_TIMEOUT = 1;
     public static final int RESULT_SOURCE_NOT_AVAILABLE = 2;
     public static final int RESULT_TARGET_NOT_AVAILABLE = 3;
-    public static final int RESULT_ALREADY_IN_PROGRESS = 4;
+
+    @Deprecated public static final int RESULT_ALREADY_IN_PROGRESS = 4;
     public static final int RESULT_EXCEPTION = 5;
     public static final int RESULT_INCORRECT_MODE = 6;
     public static final int RESULT_COMMUNICATION_FAILED = 7;
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 32930a7..14bb923 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -457,14 +457,16 @@
         private final boolean mRds;
         private final boolean mTa;
         private final boolean mAf;
+        private final boolean mEa;
 
         FmBandDescriptor(int region, int type, int lowerLimit, int upperLimit, int spacing,
-                boolean stereo, boolean rds, boolean ta, boolean af) {
+                boolean stereo, boolean rds, boolean ta, boolean af, boolean ea) {
             super(region, type, lowerLimit, upperLimit, spacing);
             mStereo = stereo;
             mRds = rds;
             mTa = ta;
             mAf = af;
+            mEa = ea;
         }
 
         /** Stereo is supported
@@ -492,6 +494,13 @@
             return mAf;
         }
 
+        /** Emergency Announcement is supported
+         * @return {@code true} if Emergency annoucement is supported, {@code false} otherwise.
+         */
+        public boolean isEaSupported() {
+            return mEa;
+        }
+
         /* Parcelable implementation */
         private FmBandDescriptor(Parcel in) {
             super(in);
@@ -499,6 +508,7 @@
             mRds = in.readByte() == 1;
             mTa = in.readByte() == 1;
             mAf = in.readByte() == 1;
+            mEa = in.readByte() == 1;
         }
 
         public static final Parcelable.Creator<FmBandDescriptor> CREATOR
@@ -519,6 +529,7 @@
             dest.writeByte((byte) (mRds ? 1 : 0));
             dest.writeByte((byte) (mTa ? 1 : 0));
             dest.writeByte((byte) (mAf ? 1 : 0));
+            dest.writeByte((byte) (mEa ? 1 : 0));
         }
 
         @Override
@@ -529,7 +540,8 @@
         @Override
         public String toString() {
             return "FmBandDescriptor [ "+ super.toString() + " mStereo=" + mStereo
-                    + ", mRds=" + mRds + ", mTa=" + mTa + ", mAf=" + mAf + "]";
+                    + ", mRds=" + mRds + ", mTa=" + mTa + ", mAf=" + mAf +
+                    ", mEa =" + mEa + "]";
         }
 
         @Override
@@ -540,6 +552,7 @@
             result = prime * result + (mRds ? 1 : 0);
             result = prime * result + (mTa ? 1 : 0);
             result = prime * result + (mAf ? 1 : 0);
+            result = prime * result + (mEa ? 1 : 0);
             return result;
         }
 
@@ -560,6 +573,8 @@
                 return false;
             if (mAf != other.isAfSupported())
                 return false;
+            if (mEa != other.isEaSupported())
+                return false;
             return true;
         }
     }
@@ -754,6 +769,7 @@
         private final boolean mRds;
         private final boolean mTa;
         private final boolean mAf;
+        private final boolean mEa;
 
         FmBandConfig(FmBandDescriptor descriptor) {
             super((BandDescriptor)descriptor);
@@ -761,15 +777,17 @@
             mRds = descriptor.isRdsSupported();
             mTa = descriptor.isTaSupported();
             mAf = descriptor.isAfSupported();
+            mEa = descriptor.isEaSupported();
         }
 
         FmBandConfig(int region, int type, int lowerLimit, int upperLimit, int spacing,
-                boolean stereo, boolean rds, boolean ta, boolean af) {
+                boolean stereo, boolean rds, boolean ta, boolean af, boolean ea) {
             super(region, type, lowerLimit, upperLimit, spacing);
             mStereo = stereo;
             mRds = rds;
             mTa = ta;
             mAf = af;
+            mEa = ea;
         }
 
         /** Get stereo enable state
@@ -800,12 +818,21 @@
             return mAf;
         }
 
+        /**
+         * Get Emergency announcement enable state
+         * @return the enable state.
+         */
+        public boolean getEa() {
+            return mEa;
+        }
+
         private FmBandConfig(Parcel in) {
             super(in);
             mStereo = in.readByte() == 1;
             mRds = in.readByte() == 1;
             mTa = in.readByte() == 1;
             mAf = in.readByte() == 1;
+            mEa = in.readByte() == 1;
         }
 
         public static final Parcelable.Creator<FmBandConfig> CREATOR
@@ -826,6 +853,7 @@
             dest.writeByte((byte) (mRds ? 1 : 0));
             dest.writeByte((byte) (mTa ? 1 : 0));
             dest.writeByte((byte) (mAf ? 1 : 0));
+            dest.writeByte((byte) (mEa ? 1 : 0));
         }
 
         @Override
@@ -837,7 +865,7 @@
         public String toString() {
             return "FmBandConfig [" + super.toString()
                     + ", mStereo=" + mStereo + ", mRds=" + mRds + ", mTa=" + mTa
-                    + ", mAf=" + mAf + "]";
+                    + ", mAf=" + mAf + ", mEa =" + mEa + "]";
         }
 
         @Override
@@ -848,6 +876,7 @@
             result = prime * result + (mRds ? 1 : 0);
             result = prime * result + (mTa ? 1 : 0);
             result = prime * result + (mAf ? 1 : 0);
+            result = prime * result + (mEa ? 1 : 0);
             return result;
         }
 
@@ -868,6 +897,8 @@
                 return false;
             if (mAf != other.mAf)
                 return false;
+            if (mEa != other.mEa)
+                return false;
             return true;
         }
 
@@ -880,6 +911,7 @@
             private boolean mRds;
             private boolean mTa;
             private boolean mAf;
+            private boolean mEa;
 
             /**
              * Constructs a new Builder with the defaults from an {@link FmBandDescriptor} .
@@ -893,6 +925,7 @@
                 mRds = descriptor.isRdsSupported();
                 mTa = descriptor.isTaSupported();
                 mAf = descriptor.isAfSupported();
+                mEa = descriptor.isEaSupported();
             }
 
             /**
@@ -906,6 +939,7 @@
                 mRds = config.getRds();
                 mTa = config.getTa();
                 mAf = config.getAf();
+                mEa = config.getEa();
             }
 
             /**
@@ -917,7 +951,7 @@
                 FmBandConfig config = new FmBandConfig(mDescriptor.getRegion(),
                         mDescriptor.getType(), mDescriptor.getLowerLimit(),
                         mDescriptor.getUpperLimit(), mDescriptor.getSpacing(),
-                        mStereo, mRds, mTa, mAf);
+                        mStereo, mRds, mTa, mAf, mEa);
                 return config;
             }
 
@@ -956,6 +990,15 @@
                 mAf = state;
                 return this;
             }
+
+            /** Set Emergency Announcement enable state
+             * @param state The new enable state.
+             * @return the same Builder instance.
+             */
+            public Builder setEa(boolean state) {
+                mEa = state;
+                return this;
+            }
         };
     }
 
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index 8b1851b..b7715da 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -95,11 +95,17 @@
      */
     public static final String METADATA_KEY_ART = "android.hardware.radio.metadata.ART";
 
+    /**
+     * The clock.
+     */
+    public static final String METADATA_KEY_CLOCK = "android.hardware.radio.metadata.CLOCK";
+
 
     private static final int METADATA_TYPE_INVALID = -1;
     private static final int METADATA_TYPE_INT = 0;
     private static final int METADATA_TYPE_TEXT = 1;
     private static final int METADATA_TYPE_BITMAP = 2;
+    private static final int METADATA_TYPE_CLOCK = 3;
 
     private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
 
@@ -116,6 +122,7 @@
         METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_TEXT);
         METADATA_KEYS_TYPE.put(METADATA_KEY_ICON, METADATA_TYPE_BITMAP);
         METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_CLOCK, METADATA_TYPE_CLOCK);
     }
 
     // keep in sync with: system/media/radio/include/system/radio_metadata.h
@@ -131,6 +138,7 @@
     private static final int NATIVE_KEY_GENRE       = 8;
     private static final int NATIVE_KEY_ICON        = 9;
     private static final int NATIVE_KEY_ART         = 10;
+    private static final int NATIVE_KEY_CLOCK       = 11;
 
     private static final SparseArray<String> NATIVE_KEY_MAPPING;
 
@@ -147,6 +155,59 @@
         NATIVE_KEY_MAPPING.put(NATIVE_KEY_GENRE, METADATA_KEY_GENRE);
         NATIVE_KEY_MAPPING.put(NATIVE_KEY_ICON, METADATA_KEY_ICON);
         NATIVE_KEY_MAPPING.put(NATIVE_KEY_ART, METADATA_KEY_ART);
+        NATIVE_KEY_MAPPING.put(NATIVE_KEY_CLOCK, METADATA_KEY_CLOCK);
+    }
+
+    /**
+     * Provides a Clock that can be used to describe time as provided by the Radio.
+     *
+     * The clock is defined by the seconds since epoch at the UTC + 0 timezone
+     * and timezone offset from UTC + 0 represented in number of minutes.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Clock implements Parcelable {
+        private final long mUtcEpochSeconds;
+        private final int mTimezoneOffsetMinutes;
+
+        public int describeContents() {
+            return 0;
+        }
+
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeLong(mUtcEpochSeconds);
+            out.writeInt(mTimezoneOffsetMinutes);
+        }
+
+        public static final Parcelable.Creator<Clock> CREATOR
+                = new Parcelable.Creator<Clock>() {
+            public Clock createFromParcel(Parcel in) {
+                return new Clock(in);
+            }
+
+            public Clock[] newArray(int size) {
+                return new Clock[size];
+            }
+        };
+
+        public Clock(long utcEpochSeconds, int timezoneOffsetMinutes) {
+            mUtcEpochSeconds = utcEpochSeconds;
+            mTimezoneOffsetMinutes = timezoneOffsetMinutes;
+        }
+
+        private Clock(Parcel in) {
+            mUtcEpochSeconds = in.readLong();
+            mTimezoneOffsetMinutes = in.readInt();
+        }
+
+        public long getUtcEpochSeconds() {
+            return mUtcEpochSeconds;
+        }
+
+        public int getTimezoneOffsetMinutes() {
+            return mTimezoneOffsetMinutes;
+        }
     }
 
     private final Bundle mBundle;
@@ -212,6 +273,17 @@
         return bmp;
     }
 
+    public Clock getClock(String key) {
+        Clock clock = null;
+        try {
+            clock = mBundle.getParcelable(key);
+        } catch (Exception e) {
+            // ignore, value was not a clock.
+            Log.w(TAG, "Failed to retrieve a key as Clock.", e);
+        }
+        return clock;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -389,6 +461,27 @@
         }
 
         /**
+         * Put a {@link RadioMetadata.Clock} into the meta data. Custom keys may be used, but if the
+         * METADATA_KEYs defined in this class are used they may only be one of the following:
+         * <ul>
+         * <li>{@link #MEADATA_KEY_CLOCK}</li>
+         * </ul>
+         *
+         * @param utcSecondsSinceEpoch Number of seconds since epoch for UTC + 0 timezone.
+         * @param timezoneOffsetInMinutes Offset of timezone from UTC + 0 in minutes.
+         * @return the same Builder instance.
+         */
+        public Builder putClock(String key, long utcSecondsSinceEpoch, int timezoneOffsetMinutes) {
+            if (!METADATA_KEYS_TYPE.containsKey(key) ||
+                    METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
+                throw new IllegalArgumentException("The " + key
+                    + " key cannot be used to put a RadioMetadata.Clock.");
+            }
+            mBundle.putParcelable(key, new Clock(utcSecondsSinceEpoch, timezoneOffsetMinutes));
+            return this;
+        }
+
+        /**
          * Creates a {@link RadioMetadata} instance with the specified fields.
          *
          * @return a new {@link RadioMetadata} object
@@ -446,4 +539,16 @@
             return 0;
         }
     }
+
+    int putClockFromNative(int nativeKey, long utcEpochSeconds, int timezoneOffsetInMinutes) {
+        Log.d(TAG, "putClockFromNative()");
+        String key = getKeyFromNativeKey(nativeKey);
+        if (!METADATA_KEYS_TYPE.containsKey(key) ||
+                METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
+              return -1;
+        }
+        mBundle.putParcelable(key, new RadioMetadata.Clock(
+            utcEpochSeconds, timezoneOffsetInMinutes));
+        return 0;
+    }
 }
diff --git a/core/java/android/hardware/radio/RadioModule.java b/core/java/android/hardware/radio/RadioModule.java
index 15916ae..fc7d0d2 100644
--- a/core/java/android/hardware/radio/RadioModule.java
+++ b/core/java/android/hardware/radio/RadioModule.java
@@ -89,6 +89,7 @@
     static final int EVENT_METADATA = 4;
     static final int EVENT_TA = 5;
     static final int EVENT_AF_SWITCH = 6;
+    static final int EVENT_EA = 7;
     static final int EVENT_CONTROL = 100;
     static final int EVENT_SERVER_DIED = 101;
 
@@ -170,6 +171,10 @@
                                 callback.onTrafficAnnouncement(msg.arg2 == 1);
                             }
                             break;
+                        case EVENT_EA:
+                            if (callback != null) {
+                                callback.onEmergencyAnnouncement(msg.arg2 == 1);
+                            }
                         case EVENT_CONTROL:
                             if (callback != null) {
                                 callback.onControlChanged(msg.arg2 == 1);
diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java
index 376900a..5c82555 100644
--- a/core/java/android/hardware/radio/RadioTuner.java
+++ b/core/java/android/hardware/radio/RadioTuner.java
@@ -281,6 +281,10 @@
          */
         public void onTrafficAnnouncement(boolean active) {}
         /**
+         * onEmergencyAnnouncement() is called when an emergency annoucement starts and stops.
+         */
+        public void onEmergencyAnnouncement(boolean active) {}
+        /**
          * onAntennaState() is called when the antenna is connected or disconnected.
          */
         public void onAntennaState(boolean connected) {}
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index bb08be2..2137c3a 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -87,12 +87,21 @@
     public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02;
 
     /**
-     * Default tag value for {@link BackupManager} traffic.
+     * Default tag value for {@link BackupManager} backup traffic; that is,
+     * traffic from the device to the storage backend.
      *
      * @hide
      */
     public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03;
 
+    /**
+     * Default tag value for {@link BackupManager} restore traffic; that is,
+     * app data retrieved from the storage backend at install time.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
+
     private static INetworkStatsService sStatsService;
 
     private synchronized static INetworkStatsService getStatsService() {
@@ -142,6 +151,16 @@
     }
 
     /**
+     * System API for restore-related support components to tag network traffic
+     * appropriately.
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagRestore() {
+        setThreadStatsTag(TAG_SYSTEM_RESTORE);
+    }
+
+    /**
      * Get the active tag used when accounting {@link Socket} traffic originating
      * from the current thread. Only one active tag per thread is supported.
      * {@link #tagSocket(Socket)}.
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index 25ef8b5..6729347 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -20,6 +20,9 @@
 
 import com.android.org.conscrypt.TrustManagerImpl;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.List;
@@ -36,7 +39,11 @@
  */
 public class X509TrustManagerExtensions {
 
-    final TrustManagerImpl mDelegate;
+    private final TrustManagerImpl mDelegate;
+    // Methods to use when mDelegate is not a TrustManagerImpl and duck typing is being used.
+    private final X509TrustManager mTrustManager;
+    private final Method mCheckServerTrusted;
+    private final Method mIsUserAddedCertificate;
 
     /**
      * Constructs a new X509TrustManagerExtensions wrapper.
@@ -47,10 +54,31 @@
     public X509TrustManagerExtensions(X509TrustManager tm) throws IllegalArgumentException {
         if (tm instanceof TrustManagerImpl) {
             mDelegate = (TrustManagerImpl) tm;
-        } else {
-            mDelegate = null;
-            throw new IllegalArgumentException("tm is an instance of " + tm.getClass().getName() +
-                    " which is not a supported type of X509TrustManager");
+            mTrustManager = null;
+            mCheckServerTrusted = null;
+            mIsUserAddedCertificate = null;
+            return;
+        }
+        // Use duck typing if possible.
+        mDelegate = null;
+        mTrustManager = tm;
+        // Check that the hostname aware checkServerTrusted is present.
+        try {
+            mCheckServerTrusted = tm.getClass().getMethod("checkServerTrusted",
+                    X509Certificate[].class,
+                    String.class,
+                    String.class);
+        } catch (NoSuchMethodException e) {
+            throw new IllegalArgumentException("Required method"
+                    + " checkServerTrusted(X509Certificate[], String, String, String) missing");
+        }
+        // Check that isUserAddedCertificate is present.
+        try {
+            mIsUserAddedCertificate = tm.getClass().getMethod("isUserAddedCertificate",
+                    X509Certificate.class);
+        } catch (NoSuchMethodException e) {
+            throw new IllegalArgumentException(
+                    "Required method isUserAddedCertificate(X509Certificate) missing");
         }
     }
 
@@ -66,7 +94,24 @@
      */
     public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
                                                     String host) throws CertificateException {
-        return mDelegate.checkServerTrusted(chain, authType, host);
+        if (mDelegate != null) {
+            return mDelegate.checkServerTrusted(chain, authType, host);
+        } else {
+            try {
+                return (List<X509Certificate>) mCheckServerTrusted.invoke(mTrustManager, chain,
+                        authType, host);
+            } catch (IllegalAccessException e) {
+                throw new CertificateException("Failed to call checkServerTrusted", e);
+            } catch (InvocationTargetException e) {
+                if (e.getCause() instanceof CertificateException) {
+                    throw (CertificateException) e.getCause();
+                }
+                if (e.getCause() instanceof RuntimeException) {
+                    throw (RuntimeException) e.getCause();
+                }
+                throw new CertificateException("checkServerTrusted failed", e.getCause());
+            }
+        }
     }
 
     /**
@@ -80,7 +125,21 @@
      * otherwise.
      */
     public boolean isUserAddedCertificate(X509Certificate cert) {
-        return mDelegate.isUserAddedCertificate(cert);
+        if (mDelegate != null) {
+            return mDelegate.isUserAddedCertificate(cert);
+        } else {
+            try {
+                return (Boolean) mIsUserAddedCertificate.invoke(mTrustManager, cert);
+            } catch (IllegalAccessException e) {
+                throw new RuntimeException("Failed to call isUserAddedCertificate", e);
+            } catch (InvocationTargetException e) {
+                if (e.getCause() instanceof RuntimeException) {
+                    throw (RuntimeException) e.getCause();
+                } else {
+                    throw new RuntimeException("isUserAddedCertificate failed", e.getCause());
+                }
+            }
+        }
     }
 
     /**
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index f346fe7..53627fc 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -35,6 +35,7 @@
     private static final String ENV_ANDROID_ROOT = "ANDROID_ROOT";
     private static final String ENV_ANDROID_DATA = "ANDROID_DATA";
     private static final String ENV_ANDROID_STORAGE = "ANDROID_STORAGE";
+    private static final String ENV_DOWNLOAD_CACHE = "DOWNLOAD_CACHE";
     private static final String ENV_OEM_ROOT = "OEM_ROOT";
     private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
 
@@ -53,11 +54,10 @@
     private static final File DIR_ANDROID_ROOT = getDirectory(ENV_ANDROID_ROOT, "/system");
     private static final File DIR_ANDROID_DATA = getDirectory(ENV_ANDROID_DATA, "/data");
     private static final File DIR_ANDROID_STORAGE = getDirectory(ENV_ANDROID_STORAGE, "/storage");
+    private static final File DIR_DOWNLOAD_CACHE = getDirectory(ENV_DOWNLOAD_CACHE, "/cache");
     private static final File DIR_OEM_ROOT = getDirectory(ENV_OEM_ROOT, "/oem");
     private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
 
-    private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
-
     private static UserEnvironment sCurrentUser;
     private static boolean sUserRequired;
 
@@ -164,34 +164,16 @@
         return DIR_VENDOR_ROOT;
     }
 
-    /**
-     * Gets the system directory available for secure storage.
-     * If Encrypted File system is enabled, it returns an encrypted directory (/data/secure/system).
-     * Otherwise, it returns the unencrypted /data/system directory.
-     * @return File object representing the secure storage system directory.
-     * @hide
-     */
+    /** {@hide} */
+    @Deprecated
     public static File getSystemSecureDirectory() {
-        if (isEncryptedFilesystemEnabled()) {
-            return new File(SECURE_DATA_DIRECTORY, "system");
-        } else {
-            return new File(DATA_DIRECTORY, "system");
-        }
+        return getDataSystemDirectory();
     }
 
-    /**
-     * Gets the data directory for secure storage.
-     * If Encrypted File system is enabled, it returns an encrypted directory (/data/secure).
-     * Otherwise, it returns the unencrypted /data directory.
-     * @return File object representing the data directory for secure storage.
-     * @hide
-     */
+    /** {@hide} */
+    @Deprecated
     public static File getSecureDataDirectory() {
-        if (isEncryptedFilesystemEnabled()) {
-            return SECURE_DATA_DIRECTORY;
-        } else {
-            return DATA_DIRECTORY;
-        }
+        return getDataDirectory();
     }
 
     /**
@@ -202,7 +184,7 @@
      * @hide
      */
     public static File getUserSystemDirectory(int userId) {
-        return new File(new File(getSystemSecureDirectory(), "users"), Integer.toString(userId));
+        return new File(new File(getDataSystemDirectory(), "users"), Integer.toString(userId));
     }
 
     /**
@@ -217,62 +199,93 @@
     }
 
     /**
-     * Returns whether the Encrypted File System feature is enabled on the device or not.
-     * @return <code>true</code> if Encrypted File System feature is enabled, <code>false</code>
-     * if disabled.
-     * @hide
-     */
-    public static boolean isEncryptedFilesystemEnabled() {
-        return SystemProperties.getBoolean(SYSTEM_PROPERTY_EFS_ENABLED, false);
-    }
-
-    private static final File DATA_DIRECTORY
-            = getDirectory("ANDROID_DATA", "/data");
-
-    /**
-     * @hide
-     */
-    private static final File SECURE_DATA_DIRECTORY
-            = getDirectory("ANDROID_SECURE_DATA", "/data/secure");
-
-    private static final File DOWNLOAD_CACHE_DIRECTORY = getDirectory("DOWNLOAD_CACHE", "/cache");
-
-    /**
      * Return the user data directory.
      */
     public static File getDataDirectory() {
-        return DATA_DIRECTORY;
+        return DIR_ANDROID_DATA;
     }
 
     /** {@hide} */
     public static File getDataDirectory(String volumeUuid) {
         if (TextUtils.isEmpty(volumeUuid)) {
-            return new File("/data");
+            return DIR_ANDROID_DATA;
         } else {
             return new File("/mnt/expand/" + volumeUuid);
         }
     }
 
     /** {@hide} */
+    public static File getDataSystemDirectory() {
+        return new File(getDataDirectory(), "system");
+    }
+
+    /** {@hide} */
+    public static File getDataSystemCredentialEncryptedDirectory() {
+        return new File(getDataDirectory(), "system_ce");
+    }
+
+    /** {@hide} */
+    public static File getDataSystemCredentialEncryptedDirectory(int userId) {
+        return new File(getDataSystemCredentialEncryptedDirectory(), String.valueOf(userId));
+    }
+
+    /** {@hide} */
     public static File getDataAppDirectory(String volumeUuid) {
         return new File(getDataDirectory(volumeUuid), "app");
     }
 
     /** {@hide} */
+    @Deprecated
     public static File getDataUserDirectory(String volumeUuid) {
+        return getDataUserCredentialEncryptedDirectory(volumeUuid);
+    }
+
+    /** {@hide} */
+    @Deprecated
+    public static File getDataUserDirectory(String volumeUuid, int userId) {
+        return getDataUserCredentialEncryptedDirectory(volumeUuid, userId);
+    }
+
+    /** {@hide} */
+    @Deprecated
+    public static File getDataUserPackageDirectory(String volumeUuid, int userId,
+            String packageName) {
+        return getDataUserCredentialEncryptedPackageDirectory(volumeUuid, userId, packageName);
+    }
+
+    /** {@hide} */
+    public static File getDataUserCredentialEncryptedDirectory(String volumeUuid) {
         return new File(getDataDirectory(volumeUuid), "user");
     }
 
     /** {@hide} */
-    public static File getDataUserDirectory(String volumeUuid, int userId) {
-        return new File(getDataUserDirectory(volumeUuid), String.valueOf(userId));
+    public static File getDataUserCredentialEncryptedDirectory(String volumeUuid, int userId) {
+        return new File(getDataUserCredentialEncryptedDirectory(volumeUuid),
+                String.valueOf(userId));
     }
 
     /** {@hide} */
-    public static File getDataUserPackageDirectory(String volumeUuid, int userId,
+    public static File getDataUserCredentialEncryptedPackageDirectory(String volumeUuid, int userId,
             String packageName) {
         // TODO: keep consistent with installd
-        return new File(getDataUserDirectory(volumeUuid, userId), packageName);
+        return new File(getDataUserCredentialEncryptedDirectory(volumeUuid, userId), packageName);
+    }
+
+    /** {@hide} */
+    public static File getDataUserDeviceEncryptedDirectory(String volumeUuid) {
+        return new File(getDataDirectory(volumeUuid), "user_de");
+    }
+
+    /** {@hide} */
+    public static File getDataUserDeviceEncryptedDirectory(String volumeUuid, int userId) {
+        return new File(getDataUserDeviceEncryptedDirectory(volumeUuid), String.valueOf(userId));
+    }
+
+    /** {@hide} */
+    public static File getDataUserDeviceEncryptedPackageDirectory(String volumeUuid, int userId,
+            String packageName) {
+        // TODO: keep consistent with installd
+        return new File(getDataUserDeviceEncryptedDirectory(volumeUuid, userId), packageName);
     }
 
     /**
@@ -539,7 +552,7 @@
      * Return the download/cache content directory.
      */
     public static File getDownloadCacheDirectory() {
-        return DOWNLOAD_CACHE_DIRECTORY;
+        return DIR_DOWNLOAD_CACHE;
     }
 
     /**
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index af4c2bc..b73d81e 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.provider.DocumentsContract.Document;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -646,4 +647,8 @@
             return EMPTY;
         }
     }
+
+    public static @Nullable File newFileOrNull(@Nullable String path) {
+        return (path != null) ? new File(path) : null;
+    }
 }
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index f55883a..7a1a6a2 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -35,4 +35,6 @@
     long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
     long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason);
     void exitIdle(String reason);
+    void downloadServiceActive(IBinder token);
+    void downloadServiceInactive();
 }
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 12cac85..b5bbbbb 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -44,7 +44,7 @@
     UserInfo getPrimaryUser();
     List<UserInfo> getUsers(boolean excludeDying);
     List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
-    boolean canAddMoreManagedProfiles(int userId);
+    boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne);
     UserInfo getProfileParent(int userHandle);
     boolean isSameProfileGroup(int userId, int otherUserId);
     UserInfo getUserInfo(int userHandle);
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 5852f5f..f2aea08 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -624,6 +624,32 @@
     }
 
     /**
+     * {@hide}
+     * This will be the new name for writeFileDescriptor, for consistency.
+     **/
+    public final void writeRawFileDescriptor(FileDescriptor val) {
+        nativeWriteFileDescriptor(mNativePtr, val);
+    }
+
+    /**
+     * {@hide}
+     * Write an array of FileDescriptor objects into the Parcel.
+     *
+     * @param value The array of objects to be written.
+     */
+    public final void writeRawFileDescriptorArray(FileDescriptor[] value) {
+        if (value != null) {
+            int N = value.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeRawFileDescriptor(value[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    /**
      * Write a byte value into the parcel at the current dataPosition(),
      * growing dataCapacity() if needed.
      */
@@ -1700,6 +1726,41 @@
         return nativeReadFileDescriptor(mNativePtr);
     }
 
+    /**
+     * {@hide}
+     * Read and return a new array of FileDescriptors from the parcel.
+     * @return the FileDescriptor array, or null if the array is null.
+     **/
+    public final FileDescriptor[] createRawFileDescriptorArray() {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        FileDescriptor[] f = new FileDescriptor[N];
+        for (int i = 0; i < N; i++) {
+            f[i] = readRawFileDescriptor();
+        }
+        return f;
+    }
+
+    /**
+     * {@hide}
+     * Read an array of FileDescriptors from a parcel.
+     * The passed array must be exactly the length of the array in the parcel.
+     * @return the FileDescriptor array, or null if the array is null.
+     **/
+    public final void readRawFileDescriptorArray(FileDescriptor[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readRawFileDescriptor();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+
     /*package*/ static native FileDescriptor openFileDescriptor(String file,
             int mode) throws FileNotFoundException;
     /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java
index 73c2c80..6f12b62 100644
--- a/core/java/android/os/ShellCommand.java
+++ b/core/java/android/os/ShellCommand.java
@@ -19,8 +19,11 @@
 import android.util.Slog;
 import com.android.internal.util.FastPrintWriter;
 
+import java.io.BufferedInputStream;
 import java.io.FileDescriptor;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.InputStream;
 import java.io.PrintWriter;
 
 /**
@@ -43,20 +46,37 @@
 
     private FastPrintWriter mOutPrintWriter;
     private FastPrintWriter mErrPrintWriter;
+    private InputStream mInputStream;
 
-    public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
-            String[] args, ResultReceiver resultReceiver) {
+    public void init(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, int firstArgPos) {
         mTarget = target;
         mIn = in;
         mOut = out;
         mErr = err;
         mArgs = args;
-        mResultReceiver = resultReceiver;
-        mCmd = args != null && args.length > 0 ? args[0] : null;
-        mArgPos = 1;
+        mResultReceiver = null;
+        mCmd = null;
+        mArgPos = firstArgPos;
         mCurArgData = null;
         mOutPrintWriter = null;
         mErrPrintWriter = null;
+    }
+
+    public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ResultReceiver resultReceiver) {
+        String cmd;
+        int start;
+        if (args != null && args.length > 0) {
+            cmd = args[0];
+            start = 1;
+        } else {
+            cmd = null;
+            start = 0;
+        }
+        init(target, in, out, err, args, start);
+        mCmd = cmd;
+        mResultReceiver = resultReceiver;
 
         if (DEBUG) Slog.d(TAG, "Starting command " + mCmd + " on " + mTarget);
         int res = -1;
@@ -111,6 +131,13 @@
         return mErrPrintWriter;
     }
 
+    public InputStream getInputStream() {
+        if (mInputStream == null) {
+            mInputStream = new BufferedInputStream(new FileInputStream(mIn));
+        }
+        return mInputStream;
+    }
+
     /**
      * Return the next option on the command line -- that is an argument that
      * starts with '-'.  If the next argument is not an option, null is returned.
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 95da438..f946ca7 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -256,6 +256,23 @@
         }
     }
 
+    /** @hide */
+    public static int parseUserArg(String arg) {
+        int userId;
+        if ("all".equals(arg)) {
+            userId = UserHandle.USER_ALL;
+        } else if ("current".equals(arg) || "cur".equals(arg)) {
+            userId = UserHandle.USER_CURRENT;
+        } else {
+            try {
+                userId = Integer.parseInt(arg);
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Bad user number: " + arg);
+            }
+        }
+        return userId;
+    }
+
     /**
      * Returns the user id of the current process
      * @return user id of the current process
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index e892349..0a149bb 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -718,7 +718,7 @@
     public boolean isUserRunning(UserHandle user) {
         try {
             return ActivityManagerNative.getDefault().isUserRunning(
-                    user.getIdentifier(), false);
+                    user.getIdentifier(), 0);
         } catch (RemoteException e) {
             return false;
         }
@@ -733,8 +733,9 @@
      */
     public boolean isUserRunningOrStopping(UserHandle user) {
         try {
+            // TODO: reconcile stopped vs stopping?
             return ActivityManagerNative.getDefault().isUserRunning(
-                    user.getIdentifier(), true);
+                    user.getIdentifier(), ActivityManager.FLAG_OR_STOPPED);
         } catch (RemoteException e) {
             return false;
         }
@@ -1077,13 +1078,15 @@
     /**
      * Checks whether it's possible to add more managed profiles. Caller must hold the MANAGE_USERS
      * permission.
+     * if allowedToRemoveOne is true and if the user already has a managed profile, then return if
+     * we could add a new managed profile to this user after removing the existing one.
      *
      * @return true if more managed profiles can be added, false if limit has been reached.
      * @hide
      */
-    public boolean canAddMoreManagedProfiles(int userId) {
+    public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) {
         try {
-            return mService.canAddMoreManagedProfiles(userId);
+            return mService.canAddMoreManagedProfiles(userId, allowedToRemoveOne);
         } catch (RemoteException re) {
             Log.w(TAG, "Could not check if we can add more managed profiles", re);
             return false;
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index b50cc79..9178ec6 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -19,6 +19,17 @@
  * @hide Only for use within the system server.
  */
 public abstract class UserManagerInternal {
+    public interface UserRestrictionsListener {
+        /**
+         * Called when a user restriction changes.
+         *
+         * @param userId target user id
+         * @param newRestrictions new user restrictions
+         * @param prevRestrictions user restrictions that were previously set
+         */
+        void onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions);
+    }
+
     /**
      * Lock that must be held when calling certain methods in this class.
      *
@@ -60,4 +71,13 @@
      */
     public abstract void setBaseUserRestrictionsByDpmsForMigration(int userId,
             Bundle baseRestrictions);
+
+    /** Return a user restriction. */
+    public abstract boolean getUserRestriction(int userId, String key);
+
+    /** Adds a listener to user restriction changes. */
+    public abstract void addUserRestrictionsListener(UserRestrictionsListener listener);
+
+    /** Remove a {@link UserRestrictionsListener}. */
+    public abstract void removeUserRestrictionsListener(UserRestrictionsListener listener);
 }
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index c4337cb..2e43ffc 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -21,8 +21,12 @@
 import android.os.IBinder;
 import android.os.IInterface;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
 import android.os.RemoteException;
 
+import java.io.FileDescriptor;
+
 /**
  * WARNING! Update IMountService.h and IMountService.cpp if you change this
  * file. In particular, the ordering of the methods below must match the
@@ -758,6 +762,22 @@
                 return _result;
             }
 
+            public boolean isConvertibleToFBE() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                boolean _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_isConvertibleToFBE, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt() != 0;
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
             public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
                     throws RemoteException {
                 Parcel _data = Parcel.obtain();
@@ -1182,14 +1202,14 @@
             }
 
             @Override
-            public void createNewUserDir(int userHandle, String path) throws RemoteException {
+            public void createUserKey(int userId, int serialNumber) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userHandle);
-                    _data.writeString(path);
-                    mRemote.transact(Stub.TRANSACTION_createNewUserDir, _data, _reply, 0);
+                    _data.writeInt(userId);
+                    _data.writeInt(serialNumber);
+                    mRemote.transact(Stub.TRANSACTION_createUserKey, _data, _reply, 0);
                     _reply.readException();
                 } finally {
                     _reply.recycle();
@@ -1198,13 +1218,81 @@
             }
 
             @Override
-            public void deleteUserKey(int userHandle) throws RemoteException {
+            public void destroyUserKey(int userId) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeInt(userHandle);
-                    mRemote.transact(Stub.TRANSACTION_deleteUserKey, _data, _reply, 0);
+                    _data.writeInt(userId);
+                    mRemote.transact(Stub.TRANSACTION_destroyUserKey, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
+            public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(userId);
+                    _data.writeInt(serialNumber);
+                    _data.writeByteArray(token);
+                    mRemote.transact(Stub.TRANSACTION_unlockUserKey, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
+            public void lockUserKey(int userId) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(userId);
+                    mRemote.transact(Stub.TRANSACTION_lockUserKey, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
+            public boolean isUserKeyUnlocked(int userId) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                boolean _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(userId);
+                    mRemote.transact(Stub.TRANSACTION_isUserKeyUnlocked, _data, _reply, 0);
+                    _reply.readException();
+                    _result = 0 != _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            @Override
+            public void prepareUserStorage(String volumeUuid, int userId, int serialNumber)
+                    throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(volumeUuid);
+                    _data.writeInt(userId);
+                    _data.writeInt(serialNumber);
+                    mRemote.transact(Stub.TRANSACTION_prepareUserStorage, _data, _reply, 0);
                     _reply.readException();
                 } finally {
                     _reply.recycle();
@@ -1228,6 +1316,25 @@
                 }
                 return _result;
             }
+
+            @Override
+            public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                ParcelFileDescriptor _result = null;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(name);
+                    mRemote.transact(Stub.TRANSACTION_mountAppFuse, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.<ParcelFileDescriptor>readParcelable(
+                            ClassLoader.getSystemClassLoader());
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
         }
 
         private static final String DESCRIPTOR = "IMountService";
@@ -1343,11 +1450,19 @@
         static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
         static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
 
-        static final int TRANSACTION_createNewUserDir = IBinder.FIRST_CALL_TRANSACTION + 62;
+        static final int TRANSACTION_createUserKey = IBinder.FIRST_CALL_TRANSACTION + 61;
+        static final int TRANSACTION_destroyUserKey = IBinder.FIRST_CALL_TRANSACTION + 62;
 
-        static final int TRANSACTION_deleteUserKey = IBinder.FIRST_CALL_TRANSACTION + 63;
+        static final int TRANSACTION_unlockUserKey = IBinder.FIRST_CALL_TRANSACTION + 63;
+        static final int TRANSACTION_lockUserKey = IBinder.FIRST_CALL_TRANSACTION + 64;
+        static final int TRANSACTION_isUserKeyUnlocked = IBinder.FIRST_CALL_TRANSACTION + 65;
 
-        static final int TRANSACTION_isPerUserEncryptionEnabled = IBinder.FIRST_CALL_TRANSACTION + 64;
+        static final int TRANSACTION_prepareUserStorage = IBinder.FIRST_CALL_TRANSACTION + 66;
+
+        static final int TRANSACTION_isPerUserEncryptionEnabled = IBinder.FIRST_CALL_TRANSACTION + 67;
+        static final int TRANSACTION_isConvertibleToFBE = IBinder.FIRST_CALL_TRANSACTION + 68;
+
+        static final int TRANSACTION_mountAppFuse = IBinder.FIRST_CALL_TRANSACTION + 69;
 
         /**
          * Cast an IBinder object into an IMountService interface, generating a
@@ -1744,6 +1859,13 @@
                     reply.writeString(contents);
                     return true;
                 }
+                case TRANSACTION_isConvertibleToFBE: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int resultCode = isConvertibleToFBE() ? 1 : 0;
+                    reply.writeNoException();
+                    reply.writeInt(resultCode);
+                    return true;
+                }
                 case TRANSACTION_resizeSecureContainer: {
                     data.enforceInterface(DESCRIPTOR);
                     String id;
@@ -1904,18 +2026,51 @@
                     reply.writeNoException();
                     return true;
                 }
-                case TRANSACTION_createNewUserDir: {
+                case TRANSACTION_createUserKey: {
                     data.enforceInterface(DESCRIPTOR);
-                    int userHandle = data.readInt();
-                    String path = data.readString();
-                    createNewUserDir(userHandle, path);
+                    int userId = data.readInt();
+                    int serialNumber = data.readInt();
+                    createUserKey(userId, serialNumber);
                     reply.writeNoException();
                     return true;
                 }
-                case TRANSACTION_deleteUserKey: {
+                case TRANSACTION_destroyUserKey: {
                     data.enforceInterface(DESCRIPTOR);
-                    int userHandle = data.readInt();
-                    deleteUserKey(userHandle);
+                    int userId = data.readInt();
+                    destroyUserKey(userId);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_unlockUserKey: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int userId = data.readInt();
+                    int serialNumber = data.readInt();
+                    byte[] token = data.createByteArray();
+                    unlockUserKey(userId, serialNumber, token);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_lockUserKey: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int userId = data.readInt();
+                    lockUserKey(userId);
+                    reply.writeNoException();
+                    return true;
+                }
+                case TRANSACTION_isUserKeyUnlocked: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int userId = data.readInt();
+                    boolean result = isUserKeyUnlocked(userId);
+                    reply.writeNoException();
+                    reply.writeInt(result ? 1 : 0);
+                    return true;
+                }
+                case TRANSACTION_prepareUserStorage: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String volumeUuid = data.readString();
+                    int userId = data.readInt();
+                    int serialNumber = data.readInt();
+                    prepareUserStorage(volumeUuid, userId, serialNumber);
                     reply.writeNoException();
                     return true;
                 }
@@ -1923,7 +2078,15 @@
                     data.enforceInterface(DESCRIPTOR);
                     boolean result = isPerUserEncryptionEnabled();
                     reply.writeNoException();
-                    reply.writeInt((result ? 1 : 0));
+                    reply.writeInt(result ? 1 : 0);
+                    return true;
+                }
+                case TRANSACTION_mountAppFuse: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String name = data.readString();
+                    ParcelFileDescriptor fd = mountAppFuse(name);
+                    reply.writeNoException();
+                    reply.writeParcelable(fd, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                     return true;
                 }
             }
@@ -2195,6 +2358,8 @@
      */
     public String getField(String field) throws RemoteException;
 
+    public boolean isConvertibleToFBE() throws RemoteException;
+
     public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException;
 
     /**
@@ -2236,24 +2401,17 @@
     public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
             throws RemoteException;
 
-    /**
-     * Creates the user data directory, possibly encrypted
-     * @param userHandle Handle of the user whose directory we are creating
-     * @param path Path at which to create the directory.
-     */
-    public void createNewUserDir(int userHandle, String path)
-        throws RemoteException;
+    public void createUserKey(int userId, int serialNumber) throws RemoteException;
+    public void destroyUserKey(int userId) throws RemoteException;
 
-    /**
-     * Securely delete the user's encryption key
-     * @param userHandle Handle of the user whose key we are deleting
-     */
-    public void deleteUserKey(int userHandle)
-        throws RemoteException;
+    public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException;
+    public void lockUserKey(int userId) throws RemoteException;
+    public boolean isUserKeyUnlocked(int userId) throws RemoteException;
 
-    /**
-     * Returns whether the current encryption type is per user.
-     */
-    public boolean isPerUserEncryptionEnabled()
-        throws RemoteException;
+    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber)
+            throws RemoteException;
+
+    public boolean isPerUserEncryptionEnabled() throws RemoteException;
+
+    public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 2ca0b20..2d9090b 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -30,6 +30,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
@@ -76,7 +77,11 @@
     /** {@hide} */
     public static final String PROP_HAS_ADOPTABLE = "vold.has_adoptable";
     /** {@hide} */
+    public static final String PROP_HAS_FBE = "vold.has_fbe";
+    /** {@hide} */
     public static final String PROP_FORCE_ADOPTABLE = "persist.fw.force_adoptable";
+    /** {@hide} */
+    public static final String PROP_EMULATE_FBE = "vold.emulate_fbe";
 
     /** {@hide} */
     public static final String UUID_PRIVATE_INTERNAL = null;
@@ -85,6 +90,8 @@
 
     /** {@hide} */
     public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;
+    /** {@hide} */
+    public static final int DEBUG_EMULATE_FBE = 1 << 1;
 
     /** {@hide} */
     public static final int FLAG_FOR_WRITE = 1 << 0;
@@ -287,7 +294,7 @@
     /**
      * Constructs a StorageManager object through which an application can
      * can communicate with the systems mount service.
-     * 
+     *
      * @param tgtLooper The {@link android.os.Looper} which events will be received on.
      *
      * <p>Applications can get instance of this class by calling
@@ -403,7 +410,7 @@
      * file matches a package ID that is owned by the calling program's UID.
      * That is, shared UID applications can attempt to mount any other
      * application's OBB that shares its UID.
-     * 
+     *
      * @param rawPath the path to the OBB file
      * @param key secret used to encrypt the OBB; may be <code>null</code> if no
      *            encryption was used on the OBB.
@@ -441,7 +448,7 @@
      * That is, shared UID applications can obtain access to any other
      * application's OBB that shares its UID.
      * <p>
-     * 
+     *
      * @param rawPath path to the OBB file
      * @param force whether to kill any programs using this in order to unmount
      *            it
@@ -465,7 +472,7 @@
 
     /**
      * Check whether an Opaque Binary Blob (OBB) is mounted or not.
-     * 
+     *
      * @param rawPath path to OBB image
      * @return true if OBB is mounted; false if not mounted or on error
      */
@@ -485,7 +492,7 @@
      * Check the mounted path of an Opaque Binary Blob (OBB) file. This will
      * give you the path to where you can obtain access to the internals of the
      * OBB.
-     * 
+     *
      * @param rawPath path to OBB image
      * @return absolute path to mounted OBB image data or <code>null</code> if
      *         not mounted or exception encountered trying to read status
@@ -960,18 +967,54 @@
     }
 
     /** {@hide} */
-    public void createNewUserDir(int userHandle, File path) {
+    public void createUserKey(int userId, int serialNumber) {
         try {
-            mMountService.createNewUserDir(userHandle, path.getAbsolutePath());
+            mMountService.createUserKey(userId, serialNumber);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
     }
 
     /** {@hide} */
-    public void deleteUserKey(int userHandle) {
+    public void destroyUserKey(int userId) {
         try {
-            mMountService.deleteUserKey(userHandle);
+            mMountService.destroyUserKey(userId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /** {@hide} */
+    public void unlockUserKey(int userId, int serialNumber, byte[] token) {
+        try {
+            mMountService.unlockUserKey(userId, serialNumber, token);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /** {@hide} */
+    public void lockUserKey(int userId) {
+        try {
+            mMountService.lockUserKey(userId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /** {@hide} */
+    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber) {
+        try {
+            mMountService.prepareUserStorage(volumeUuid, userId, serialNumber);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /** {@hide} */
+    public boolean isUserKeyUnlocked(int userId) {
+        try {
+            return mMountService.isUserKeyUnlocked(userId);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -1007,6 +1050,15 @@
         return path;
     }
 
+    /** {@hide} */
+    public ParcelFileDescriptor mountAppFuse(String name) {
+        try {
+            return mMountService.mountAppFuse(name);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
     /// Consts to match the password types in cryptfs.h
     /** @hide */
     public static final int CRYPT_TYPE_PASSWORD = 0;
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index db04c71..3e496b6 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -23,14 +23,15 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnKeyListener;
+import android.view.ViewGroup;
 import android.widget.ListView;
 
 /**
@@ -179,6 +180,27 @@
     }
 
     @Override
+    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        TypedArray a = getActivity().obtainStyledAttributes(null,
+                com.android.internal.R.styleable.PreferenceFragment,
+                com.android.internal.R.attr.preferenceFragmentStyle,
+                0);
+
+        ListView lv = (ListView) view.findViewById(android.R.id.list);
+        if (lv != null) {
+            Drawable divider =
+                    a.getDrawable(com.android.internal.R.styleable.PreferenceFragment_divider);
+            if (divider != null) {
+                lv.setDivider(divider);
+            }
+        }
+
+        a.recycle();
+    }
+
+    @Override
     public void onActivityCreated(@Nullable Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java
index 9c3cefc..aa8674e 100644
--- a/core/java/android/preference/SwitchPreference.java
+++ b/core/java/android/preference/SwitchPreference.java
@@ -122,7 +122,7 @@
     protected void onBindView(View view) {
         super.onBindView(view);
 
-        View checkableView = view.findViewById(com.android.internal.R.id.switchWidget);
+        View checkableView = view.findViewById(com.android.internal.R.id.switch_widget);
         if (checkableView != null && checkableView instanceof Checkable) {
             if (checkableView instanceof Switch) {
                 final Switch switchView = (Switch) checkableView;
diff --git a/core/java/android/print/IPrintSpooler.aidl b/core/java/android/print/IPrintSpooler.aidl
index 7b2cf25..db2bf1a 100644
--- a/core/java/android/print/IPrintSpooler.aidl
+++ b/core/java/android/print/IPrintSpooler.aidl
@@ -46,4 +46,5 @@
     void writePrintJobData(in ParcelFileDescriptor fd, in PrintJobId printJobId);
     void setClient(IPrintSpoolerClient client);
     void setPrintJobCancelling(in PrintJobId printJobId, boolean cancelling);
+    void removeApprovedPrintService(in ComponentName serviceToRemove);
 }
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index 90d30d6..2afbb99 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -60,7 +60,7 @@
     private Margins mMinMargins;
 
     private int mColorMode;
-    private int mDuplexMode = DUPLEX_MODE_NONE;
+    private int mDuplexMode;
 
     PrintAttributes() {
         /* hide constructor */
@@ -403,7 +403,7 @@
         mResolution = null;
         mMinMargins = null;
         mColorMode = 0;
-        mDuplexMode = DUPLEX_MODE_NONE;
+        mDuplexMode = 0;
     }
 
     /**
@@ -1427,10 +1427,6 @@
 
         /**
          * Creates a new {@link PrintAttributes} instance.
-         * <p>
-         * If you do not specify a duplex mode, the default
-         * {@link #DUPLEX_MODE_NONE} will be used.
-         * </p>
          *
          * @return The new instance.
          */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 37f2c04..9034cc9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6285,7 +6285,10 @@
        public static final String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
 
        /**
-        * Whether the device has been provisioned (0 = false, 1 = true)
+        * Whether the device has been provisioned (0 = false, 1 = true).
+        * <p>On a multiuser device with a separate system user, the screen may be locked
+        * as soon as this is set to true and further activities cannot be launched on the
+        * system user unless they are marked to show over keyguard.
         */
        public static final String DEVICE_PROVISIONED = "device_provisioned";
 
diff --git a/core/java/android/security/net/config/ApplicationConfig.java b/core/java/android/security/net/config/ApplicationConfig.java
new file mode 100644
index 0000000..b627641
--- /dev/null
+++ b/core/java/android/security/net/config/ApplicationConfig.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.Pair;
+import java.util.Locale;
+import java.util.Set;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * An application's network security configuration.
+ *
+ * <p>{@link #getConfigForHostname(String)} provides a means to obtain network security
+ * configuration to be used for communicating with a specific hostname.</p>
+ *
+ * @hide
+ */
+public final class ApplicationConfig {
+    private static ApplicationConfig sInstance;
+    private static Object sLock = new Object();
+
+    private Set<Pair<Domain, NetworkSecurityConfig>> mConfigs;
+    private NetworkSecurityConfig mDefaultConfig;
+    private X509TrustManager mTrustManager;
+
+    private ConfigSource mConfigSource;
+    private boolean mInitialized;
+    private final Object mLock = new Object();
+
+    public ApplicationConfig(ConfigSource configSource) {
+        mConfigSource = configSource;
+        mInitialized = false;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasPerDomainConfigs() {
+        ensureInitialized();
+        return mConfigs != null && !mConfigs.isEmpty();
+    }
+
+    /**
+     * Get the {@link NetworkSecurityConfig} corresponding to the provided hostname.
+     * When matching the most specific matching domain rule will be used, if no match exists
+     * then the default configuration will be returned.
+     *
+     * {@code NetworkSecurityConfig} objects returned by this method can be safely cached for
+     * {@code hostname}. Subsequent calls with the same hostname will always return the same
+     * {@code NetworkSecurityConfig}.
+     *
+     * @return {@link NetworkSecurityConfig} to be used to determine
+     * the network security configuration for connections to {@code hostname}.
+     */
+    public NetworkSecurityConfig getConfigForHostname(String hostname) {
+        ensureInitialized();
+        if (hostname.isEmpty() || mConfigs == null) {
+            return mDefaultConfig;
+        }
+        if (hostname.charAt(0) ==  '.') {
+            throw new IllegalArgumentException("hostname must not begin with a .");
+        }
+        // Domains are case insensitive.
+        hostname = hostname.toLowerCase(Locale.US);
+        // Normalize hostname by removing trailing . if present, all Domain hostnames are
+        // absolute.
+        if (hostname.charAt(hostname.length() - 1) == '.') {
+            hostname = hostname.substring(0, hostname.length() - 1);
+        }
+        // Find the Domain -> NetworkSecurityConfig entry with the most specific matching
+        // Domain entry for hostname.
+        // TODO: Use a smarter data structure for the lookup.
+        Pair<Domain, NetworkSecurityConfig> bestMatch = null;
+        for (Pair<Domain, NetworkSecurityConfig> entry : mConfigs) {
+            Domain domain = entry.first;
+            NetworkSecurityConfig config = entry.second;
+            // Check for an exact match.
+            if (domain.hostname.equals(hostname)) {
+                return config;
+            }
+            // Otherwise check if the Domain includes sub-domains and that the hostname is a
+            // sub-domain of the Domain.
+            if (domain.subdomainsIncluded
+                    && hostname.endsWith(domain.hostname)
+                    && hostname.charAt(hostname.length() - domain.hostname.length() - 1) == '.') {
+                if (bestMatch == null) {
+                    bestMatch = entry;
+                } else if (domain.hostname.length() > bestMatch.first.hostname.length()) {
+                    bestMatch = entry;
+                }
+            }
+        }
+        if (bestMatch != null) {
+            return bestMatch.second;
+        }
+        // If no match was found use the default configuration.
+        return mDefaultConfig;
+    }
+
+    /**
+     * Returns the {@link X509TrustManager} that implements the checking of trust anchors and
+     * certificate pinning based on this configuration.
+     */
+    public X509TrustManager getTrustManager() {
+        ensureInitialized();
+        return mTrustManager;
+    }
+
+    private void ensureInitialized() {
+        synchronized(mLock) {
+            if (mInitialized) {
+                return;
+            }
+            mConfigs = mConfigSource.getPerDomainConfigs();
+            mDefaultConfig = mConfigSource.getDefaultConfig();
+            mConfigSource = null;
+            mTrustManager = new RootTrustManager(this);
+            mInitialized = true;
+        }
+    }
+
+    public static void setDefaultInstance(ApplicationConfig config) {
+        synchronized (sLock) {
+            sInstance = config;
+        }
+    }
+
+    public static ApplicationConfig getDefaultInstance() {
+        synchronized (sLock) {
+            return sInstance;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java b/core/java/android/security/net/config/CertificateSource.java
similarity index 68%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
copy to core/java/android/security/net/config/CertificateSource.java
index f187178..386354d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
+++ b/core/java/android/security/net/config/CertificateSource.java
@@ -14,13 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.recents.events.activity;
+package android.security.net.config;
 
-import com.android.systemui.recents.events.EventBus;
+import java.util.Set;
+import java.security.cert.X509Certificate;
 
-/**
- * This is sent when the window animation into Recents starts.
- */
-public class EnterRecentsWindowAnimationStartedEvent extends EventBus.Event {
-    // Simple event
+/** @hide */
+public interface CertificateSource {
+    Set<X509Certificate> getCertificates();
 }
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
new file mode 100644
index 0000000..2ba38c21
--- /dev/null
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.ArraySet;
+import java.util.Set;
+import java.security.cert.X509Certificate;
+
+/** @hide */
+public final class CertificatesEntryRef {
+    private final CertificateSource mSource;
+    private final boolean mOverridesPins;
+
+    public CertificatesEntryRef(CertificateSource source, boolean overridesPins) {
+        mSource = source;
+        mOverridesPins = overridesPins;
+    }
+
+    public Set<TrustAnchor> getTrustAnchors() {
+        // TODO: cache this [but handle mutable sources]
+        Set<TrustAnchor> anchors = new ArraySet<TrustAnchor>();
+        for (X509Certificate cert : mSource.getCertificates()) {
+            anchors.add(new TrustAnchor(cert, mOverridesPins));
+        }
+        return anchors;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java b/core/java/android/security/net/config/ConfigSource.java
similarity index 68%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
copy to core/java/android/security/net/config/ConfigSource.java
index f187178..4adf265 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
+++ b/core/java/android/security/net/config/ConfigSource.java
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.recents.events.activity;
+package android.security.net.config;
 
-import com.android.systemui.recents.events.EventBus;
+import android.util.Pair;
+import java.util.Set;
 
-/**
- * This is sent when the window animation into Recents starts.
- */
-public class EnterRecentsWindowAnimationStartedEvent extends EventBus.Event {
-    // Simple event
+/** @hide */
+public interface ConfigSource {
+    Set<Pair<Domain, NetworkSecurityConfig>> getPerDomainConfigs();
+    NetworkSecurityConfig getDefaultConfig();
 }
diff --git a/core/java/android/security/net/config/Domain.java b/core/java/android/security/net/config/Domain.java
new file mode 100644
index 0000000..5bb727a
--- /dev/null
+++ b/core/java/android/security/net/config/Domain.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import java.util.Locale;
+/** @hide */
+public final class Domain {
+    /**
+     * Lower case hostname for this domain rule.
+     */
+    public final String hostname;
+
+    /**
+     * Whether this domain includes subdomains.
+     */
+    public final boolean subdomainsIncluded;
+
+    public Domain(String hostname, boolean subdomainsIncluded) {
+        if (hostname == null) {
+            throw new NullPointerException("Hostname must not be null");
+        }
+        this.hostname = hostname.toLowerCase(Locale.US);
+        this.subdomainsIncluded = subdomainsIncluded;
+    }
+
+    @Override
+    public int hashCode() {
+        return hostname.hashCode() ^ (subdomainsIncluded ? 1231 : 1237);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (!(other instanceof Domain)) {
+            return false;
+        }
+        Domain otherDomain = (Domain) other;
+        return otherDomain.subdomainsIncluded == this.subdomainsIncluded &&
+                otherDomain.hostname.equals(this.hostname);
+    }
+}
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
new file mode 100644
index 0000000..1973ef1
--- /dev/null
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.ArraySet;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Set;
+
+/**
+ * {@link CertificateSource} which provides certificates from trusted certificate entries of a
+ * {@link KeyStore}.
+ */
+class KeyStoreCertificateSource implements CertificateSource {
+    private final Object mLock = new Object();
+    private final KeyStore mKeyStore;
+    private Set<X509Certificate> mCertificates;
+
+    public KeyStoreCertificateSource(KeyStore ks) {
+        mKeyStore = ks;
+    }
+
+    @Override
+    public Set<X509Certificate> getCertificates() {
+        synchronized (mLock) {
+            if (mCertificates != null) {
+                return mCertificates;
+            }
+            try {
+                Set<X509Certificate> certificates = new ArraySet<>(mKeyStore.size());
+                for (Enumeration<String> en = mKeyStore.aliases(); en.hasMoreElements();) {
+                    String alias = en.nextElement();
+                    if (!mKeyStore.isCertificateEntry(alias)) {
+                        continue;
+                    }
+                    X509Certificate cert = (X509Certificate) mKeyStore.getCertificate(alias);
+                    if (cert != null) {
+                        certificates.add(cert);
+                    }
+                }
+                mCertificates = certificates;
+                return mCertificates;
+            } catch (KeyStoreException e) {
+                throw new RuntimeException("Failed to load certificates from KeyStore", e);
+            }
+        }
+    }
+}
diff --git a/core/java/android/security/net/config/KeyStoreConfigSource.java b/core/java/android/security/net/config/KeyStoreConfigSource.java
new file mode 100644
index 0000000..8d4f098
--- /dev/null
+++ b/core/java/android/security/net/config/KeyStoreConfigSource.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.Pair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.util.Set;
+
+/**
+ * {@link ConfigSource} with a single default config based on a {@link KeyStore} and no per domain
+ * configs.
+ */
+class KeyStoreConfigSource implements ConfigSource {
+    private final NetworkSecurityConfig mConfig;
+
+    public KeyStoreConfigSource(KeyStore ks) {
+        mConfig = new NetworkSecurityConfig.Builder()
+                .addCertificatesEntryRef(
+                        // Use the KeyStore and do not override pins (of which there are none).
+                        new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false))
+                .build();
+    }
+
+    @Override
+    public Set<Pair<Domain, NetworkSecurityConfig>> getPerDomainConfigs() {
+        return null;
+    }
+
+    @Override
+    public NetworkSecurityConfig getDefaultConfig() {
+        return mConfig;
+    }
+}
+
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
new file mode 100644
index 0000000..8906f9b
--- /dev/null
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.ArraySet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * @hide
+ */
+public final class NetworkSecurityConfig {
+    /** @hide */
+    public static final boolean DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED = true;
+    /** @hide */
+    public static final boolean DEFAULT_HSTS_ENFORCED = false;
+    public static final NetworkSecurityConfig DEFAULT = getDefaultBuilder().build();
+
+    private final boolean mCleartextTrafficPermitted;
+    private final boolean mHstsEnforced;
+    private final PinSet mPins;
+    private final List<CertificatesEntryRef> mCertificatesEntryRefs;
+    private Set<TrustAnchor> mAnchors;
+    private final Object mAnchorsLock = new Object();
+    private NetworkSecurityTrustManager mTrustManager;
+    private final Object mTrustManagerLock = new Object();
+
+    private NetworkSecurityConfig(boolean cleartextTrafficPermitted, boolean hstsEnforced,
+            PinSet pins, List<CertificatesEntryRef> certificatesEntryRefs) {
+        mCleartextTrafficPermitted = cleartextTrafficPermitted;
+        mHstsEnforced = hstsEnforced;
+        mPins = pins;
+        mCertificatesEntryRefs = certificatesEntryRefs;
+    }
+
+    public Set<TrustAnchor> getTrustAnchors() {
+        synchronized (mAnchorsLock) {
+            if (mAnchors != null) {
+                return mAnchors;
+            }
+            Set<TrustAnchor> anchors = new ArraySet<TrustAnchor>();
+            for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
+                anchors.addAll(ref.getTrustAnchors());
+            }
+            mAnchors = anchors;
+            return anchors;
+        }
+    }
+
+    public boolean isCleartextTrafficPermitted() {
+        return mCleartextTrafficPermitted;
+    }
+
+    public boolean isHstsEnforced() {
+        return mHstsEnforced;
+    }
+
+    public PinSet getPins() {
+        return mPins;
+    }
+
+    public NetworkSecurityTrustManager getTrustManager() {
+        synchronized(mTrustManagerLock) {
+            if (mTrustManager == null) {
+                mTrustManager = new NetworkSecurityTrustManager(this);
+            }
+            return mTrustManager;
+        }
+    }
+
+    void onTrustStoreChange() {
+        synchronized (mAnchorsLock) {
+            mAnchors = null;
+        }
+    }
+
+    /**
+     * Return a {@link Builder} for the default {@code NetworkSecurityConfig}.
+     *
+     * <p>
+     * The default configuration has the following properties:
+     * <ol>
+     * <li>Cleartext traffic is permitted.</li>
+     * <li>HSTS is not enforced.</li>
+     * <li>No certificate pinning is used.</li>
+     * <li>The system and user added trusted certificate stores are trusted for connections.</li>
+     * </ol>
+     *
+     * @hide
+     */
+    public static final Builder getDefaultBuilder() {
+        return new Builder()
+                .setCleartextTrafficPermitted(DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED)
+                .setHstsEnforced(DEFAULT_HSTS_ENFORCED)
+                // System certificate store, does not bypass static pins.
+                .addCertificatesEntryRef(
+                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                // User certificate store, does not bypass static pins.
+                .addCertificatesEntryRef(
+                        new CertificatesEntryRef(UserCertificateSource.getInstance(), false));
+    }
+
+    /**
+     * Builder for creating {@code NetworkSecurityConfig} objects.
+     * @hide
+     */
+    public static final class Builder {
+        private List<CertificatesEntryRef> mCertificatesEntryRefs;
+        private PinSet mPinSet;
+        private boolean mCleartextTrafficPermitted = DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED;
+        private boolean mHstsEnforced = DEFAULT_HSTS_ENFORCED;
+        private boolean mCleartextTrafficPermittedSet = false;
+        private boolean mHstsEnforcedSet = false;
+        private Builder mParentBuilder;
+
+        /**
+         * Sets the parent {@code Builder} for this {@code Builder}.
+         * The parent will be used to determine values not configured in this {@code Builder}
+         * in {@link Builder#build()}, recursively if needed.
+         */
+        public Builder setParent(Builder parent) {
+            // Sanity check to avoid adding loops.
+            Builder current = parent;
+            while (current != null) {
+                if (current == this) {
+                    throw new IllegalArgumentException("Loops are not allowed in Builder parents");
+                }
+                current = current.getParent();
+            }
+            mParentBuilder = parent;
+            return this;
+        }
+
+        public Builder getParent() {
+            return mParentBuilder;
+        }
+
+        public Builder setPinSet(PinSet pinSet) {
+            mPinSet = pinSet;
+            return this;
+        }
+
+        private PinSet getEffectivePinSet() {
+            if (mPinSet != null) {
+                return mPinSet;
+            }
+            if (mParentBuilder != null) {
+                return mParentBuilder.getEffectivePinSet();
+            }
+            return PinSet.EMPTY_PINSET;
+        }
+
+        public Builder setCleartextTrafficPermitted(boolean cleartextTrafficPermitted) {
+            mCleartextTrafficPermitted = cleartextTrafficPermitted;
+            mCleartextTrafficPermittedSet = true;
+            return this;
+        }
+
+        private boolean getEffectiveCleartextTrafficPermitted() {
+            if (mCleartextTrafficPermittedSet) {
+                return mCleartextTrafficPermitted;
+            }
+            if (mParentBuilder != null) {
+                return mParentBuilder.getEffectiveCleartextTrafficPermitted();
+            }
+            return DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED;
+        }
+
+        public Builder setHstsEnforced(boolean hstsEnforced) {
+            mHstsEnforced = hstsEnforced;
+            mHstsEnforcedSet = true;
+            return this;
+        }
+
+        private boolean getEffectiveHstsEnforced() {
+            if (mHstsEnforcedSet) {
+                return mHstsEnforced;
+            }
+            if (mParentBuilder != null) {
+                return mParentBuilder.getEffectiveHstsEnforced();
+            }
+            return DEFAULT_HSTS_ENFORCED;
+        }
+
+        public Builder addCertificatesEntryRef(CertificatesEntryRef ref) {
+            if (mCertificatesEntryRefs == null) {
+                mCertificatesEntryRefs = new ArrayList<CertificatesEntryRef>();
+            }
+            mCertificatesEntryRefs.add(ref);
+            return this;
+        }
+
+        public Builder addCertificatesEntryRefs(Collection<? extends CertificatesEntryRef> refs) {
+            if (mCertificatesEntryRefs == null) {
+                mCertificatesEntryRefs = new ArrayList<CertificatesEntryRef>();
+            }
+            mCertificatesEntryRefs.addAll(refs);
+            return this;
+        }
+
+        private List<CertificatesEntryRef> getEffectiveCertificatesEntryRefs() {
+            if (mCertificatesEntryRefs != null) {
+                return mCertificatesEntryRefs;
+            }
+            if (mParentBuilder != null) {
+                return mParentBuilder.getEffectiveCertificatesEntryRefs();
+            }
+            return Collections.<CertificatesEntryRef>emptyList();
+        }
+
+        public boolean hasCertificatesEntryRefs() {
+            return mCertificatesEntryRefs != null;
+        }
+
+        List<CertificatesEntryRef> getCertificatesEntryRefs() {
+            return mCertificatesEntryRefs;
+        }
+
+        public NetworkSecurityConfig build() {
+            boolean cleartextPermitted = getEffectiveCleartextTrafficPermitted();
+            boolean hstsEnforced = getEffectiveHstsEnforced();
+            PinSet pinSet = getEffectivePinSet();
+            List<CertificatesEntryRef> entryRefs = getEffectiveCertificatesEntryRefs();
+            return new NetworkSecurityConfig(cleartextPermitted, hstsEnforced, pinSet, entryRefs);
+        }
+    }
+}
diff --git a/core/java/android/security/net/config/NetworkSecurityConfigProvider.java b/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
new file mode 100644
index 0000000..ca8cdae
--- /dev/null
+++ b/core/java/android/security/net/config/NetworkSecurityConfigProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import java.security.Provider;
+
+/** @hide */
+public final class NetworkSecurityConfigProvider extends Provider {
+
+    private static String PREFIX =
+            NetworkSecurityConfigProvider.class.getPackage().getName() + ".";
+
+    public NetworkSecurityConfigProvider() {
+        // TODO: More clever name than this
+        super("AndroidNSSP", 1.0, "Android Network Security Policy Provider");
+        put("TrustManagerFactory.PKIX", PREFIX + "RootTrustManagerFactorySpi");
+        put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
+    }
+}
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
new file mode 100644
index 0000000..7f5b3ca
--- /dev/null
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import com.android.org.conscrypt.TrustManagerImpl;
+
+import android.util.ArrayMap;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * {@link X509TrustManager} that implements the trust anchor and pinning for a
+ * given {@link NetworkSecurityConfig}.
+ * @hide
+ */
+public class NetworkSecurityTrustManager implements X509TrustManager {
+    // TODO: Replace this with a general X509TrustManager and use duck-typing.
+    private final TrustManagerImpl mDelegate;
+    private final NetworkSecurityConfig mNetworkSecurityConfig;
+
+    public NetworkSecurityTrustManager(NetworkSecurityConfig config) {
+        if (config == null) {
+            throw new NullPointerException("config must not be null");
+        }
+        mNetworkSecurityConfig = config;
+        // TODO: Create our own better KeyStoreImpl
+        try {
+            KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
+            store.load(null);
+            int certNum = 0;
+            for (TrustAnchor anchor : mNetworkSecurityConfig.getTrustAnchors()) {
+                store.setEntry(String.valueOf(certNum++),
+                        new KeyStore.TrustedCertificateEntry(anchor.certificate),
+                        null);
+            }
+            mDelegate = new TrustManagerImpl(store);
+        } catch (GeneralSecurityException | IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        throw new CertificateException("Client authentication not supported");
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] certs, String authType)
+            throws CertificateException {
+        checkServerTrusted(certs, authType, null);
+    }
+
+    /**
+     * Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
+     * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * modify without modifying those callers.
+     */
+    public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
+            String host) throws CertificateException {
+        List<X509Certificate> trustedChain = mDelegate.checkServerTrusted(certs, authType, host);
+        checkPins(trustedChain);
+        return trustedChain;
+    }
+
+    /**
+     * Check if the provided certificate is a user added certificate authority.
+     * This is required by android.net.http.X509TrustManagerExtensions.
+     */
+    public boolean isUserAddedCertificate(X509Certificate cert) {
+        // TODO: Figure out the right way to handle this, and if it is still even used.
+        return false;
+    }
+
+    private void checkPins(List<X509Certificate> chain) throws CertificateException {
+        PinSet pinSet = mNetworkSecurityConfig.getPins();
+        if (pinSet.pins.isEmpty()
+                || System.currentTimeMillis() > pinSet.expirationTime
+                || !isPinningEnforced(chain)) {
+            return;
+        }
+        Set<String> pinAlgorithms = pinSet.getPinAlgorithms();
+        Map<String, MessageDigest> digestMap = new ArrayMap<String, MessageDigest>(
+                pinAlgorithms.size());
+        for (int i = chain.size() - 1; i >= 0 ; i--) {
+            X509Certificate cert = chain.get(i);
+            byte[] encodedSPKI = cert.getPublicKey().getEncoded();
+            for (String algorithm : pinAlgorithms) {
+                MessageDigest md = digestMap.get(algorithm);
+                if (md == null) {
+                    try {
+                        md = MessageDigest.getInstance(algorithm);
+                    } catch (GeneralSecurityException e) {
+                        throw new RuntimeException(e);
+                    }
+                    digestMap.put(algorithm, md);
+                }
+                if (pinSet.pins.contains(new Pin(algorithm, md.digest(encodedSPKI)))) {
+                    return;
+                }
+            }
+        }
+
+        // TODO: Throw a subclass of CertificateException which indicates a pinning failure.
+        throw new CertificateException("Pin verification failed");
+    }
+
+    private boolean isPinningEnforced(List<X509Certificate> chain) throws CertificateException {
+        if (chain.isEmpty()) {
+            return false;
+        }
+        X509Certificate anchorCert = chain.get(chain.size() - 1);
+        TrustAnchor chainAnchor = null;
+        // TODO: faster lookup
+        for (TrustAnchor anchor : mNetworkSecurityConfig.getTrustAnchors()) {
+            if (anchor.certificate.equals(anchorCert)) {
+                chainAnchor = anchor;
+                break;
+            }
+        }
+        if (chainAnchor == null) {
+            throw new CertificateException("Trusted chain does not end in a TrustAnchor");
+        }
+        return !chainAnchor.overridesPins;
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return new X509Certificate[0];
+    }
+}
diff --git a/core/java/android/security/net/config/Pin.java b/core/java/android/security/net/config/Pin.java
new file mode 100644
index 0000000..94520e2
--- /dev/null
+++ b/core/java/android/security/net/config/Pin.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 android.security.net.config;
+
+import java.util.Arrays;
+
+/** @hide */
+public final class Pin {
+    public final String digestAlgorithm;
+    public final byte[] digest;
+
+    private final int mHashCode;
+
+    public Pin(String digestAlgorithm, byte[] digest) {
+        this.digestAlgorithm = digestAlgorithm;
+        this.digest = digest;
+        mHashCode = Arrays.hashCode(digest) ^ digestAlgorithm.hashCode();
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean isSupportedDigestAlgorithm(String algorithm) {
+        // Currently only SHA-256 is supported. SHA-512 if/once Chromium networking stack
+        // supports it.
+        return "SHA-256".equalsIgnoreCase(algorithm);
+    }
+
+    /**
+     * @hide
+     */
+    public static int getDigestLength(String algorithm) {
+        if ("SHA-256".equalsIgnoreCase(algorithm)) {
+            return 32;
+        }
+        throw new IllegalArgumentException("Unsupported digest algorithm: " + algorithm);
+    }
+
+    @Override
+    public int hashCode() {
+        return mHashCode;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof Pin)) {
+            return false;
+        }
+        Pin other = (Pin) obj;
+        if (other.hashCode() != mHashCode) {
+            return false;
+        }
+        if (!Arrays.equals(digest, other.digest)) {
+            return false;
+        }
+        if (!digestAlgorithm.equals(other.digestAlgorithm)) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/core/java/android/security/net/config/PinSet.java b/core/java/android/security/net/config/PinSet.java
new file mode 100644
index 0000000..d3c975e
--- /dev/null
+++ b/core/java/android/security/net/config/PinSet.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.ArraySet;
+import java.util.Collections;
+import java.util.Set;
+
+/** @hide */
+public final class PinSet {
+    public static final PinSet EMPTY_PINSET =
+            new PinSet(Collections.<Pin>emptySet(), Long.MAX_VALUE);
+    public final long expirationTime;
+    public final Set<Pin> pins;
+
+    public PinSet(Set<Pin> pins, long expirationTime) {
+        if (pins == null) {
+            throw new NullPointerException("pins must not be null");
+        }
+        this.pins = pins;
+        this.expirationTime = expirationTime;
+    }
+
+    Set<String> getPinAlgorithms() {
+        // TODO: Cache this.
+        Set<String> algorithms = new ArraySet<String>();
+        for (Pin pin : pins) {
+            algorithms.add(pin.digestAlgorithm);
+        }
+        return algorithms;
+    }
+}
diff --git a/core/java/android/security/net/config/ResourceCertificateSource.java b/core/java/android/security/net/config/ResourceCertificateSource.java
new file mode 100644
index 0000000..06dd9d4
--- /dev/null
+++ b/core/java/android/security/net/config/ResourceCertificateSource.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.content.Context;
+import android.util.ArraySet;
+import libcore.io.IoUtils;
+import java.io.InputStream;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * {@link CertificateSource} based on certificates contained in an application resource file.
+ * @hide
+ */
+public class ResourceCertificateSource implements CertificateSource {
+    private Set<X509Certificate> mCertificates;
+    private final int  mResourceId;
+    private Context mContext;
+    private final Object mLock = new Object();
+
+    public ResourceCertificateSource(int resourceId, Context context) {
+        mResourceId = resourceId;
+        mContext = context.getApplicationContext();
+    }
+
+    @Override
+    public Set<X509Certificate> getCertificates() {
+        synchronized (mLock) {
+            if (mCertificates != null) {
+                return mCertificates;
+            }
+            Set<X509Certificate> certificates = new ArraySet<X509Certificate>();
+            Collection<? extends Certificate> certs;
+            InputStream in = null;
+            try {
+                CertificateFactory factory = CertificateFactory.getInstance("X.509");
+                in = mContext.getResources().openRawResource(mResourceId);
+                certs = factory.generateCertificates(in);
+            } catch (CertificateException e) {
+                throw new RuntimeException("Failed to load trust anchors from id " + mResourceId,
+                        e);
+            } finally {
+                IoUtils.closeQuietly(in);
+            }
+            for (Certificate cert : certs) {
+                    certificates.add((X509Certificate) cert);
+            }
+            mCertificates = certificates;
+            mContext = null;
+            return mCertificates;
+        }
+    }
+}
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
new file mode 100644
index 0000000..b87bf1f
--- /dev/null
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * {@link X509TrustManager} based on an {@link ApplicationConfig}.
+ *
+ * <p>This {@code X509TrustManager} delegates to the specific trust manager for the hostname
+ * being used for the connection (See {@link ApplicationConfig#getConfigForHostname(String)} and
+ * {@link NetworkSecurityTrustManager}).</p>
+ *
+ * Note that if the {@code ApplicationConfig} has per-domain configurations the hostname aware
+ * {@link #checkServerTrusted(X509Certificate[], String String)} must be used instead of the normal
+ * non-aware call.
+ * @hide */
+public class RootTrustManager implements X509TrustManager {
+    private final ApplicationConfig mConfig;
+    private static final X509Certificate[] EMPTY_ISSUERS = new X509Certificate[0];
+
+    public RootTrustManager(ApplicationConfig config) {
+        if (config == null) {
+            throw new NullPointerException("config must not be null");
+        }
+        mConfig = config;
+    }
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        throw new CertificateException("Client authentication not supported");
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] certs, String authType)
+            throws CertificateException {
+        if (mConfig.hasPerDomainConfigs()) {
+            throw new CertificateException(
+                    "Domain specific configurations require that hostname aware"
+                    + " checkServerTrusted(X509Certificate[], String, String) is used");
+        }
+        NetworkSecurityConfig config = mConfig.getConfigForHostname("");
+        config.getTrustManager().checkServerTrusted(certs, authType);
+    }
+
+    /**
+     * Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
+     * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+     * modify without modifying those callers.
+     */
+    public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
+            String hostname) throws CertificateException {
+        NetworkSecurityConfig config = mConfig.getConfigForHostname(hostname);
+        return config.getTrustManager().checkServerTrusted(certs, authType, hostname);
+    }
+
+    /**
+     * Check if the provided certificate is a user added certificate authority.
+     * This is required by android.net.http.X509TrustManagerExtensions.
+     */
+    public boolean isUserAddedCertificate(X509Certificate cert) {
+        // TODO: Figure out the right way to handle this, and if it is still even used.
+        return false;
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return EMPTY_ISSUERS;
+    }
+}
diff --git a/core/java/android/security/net/config/RootTrustManagerFactorySpi.java b/core/java/android/security/net/config/RootTrustManagerFactorySpi.java
new file mode 100644
index 0000000..0a1fe88
--- /dev/null
+++ b/core/java/android/security/net/config/RootTrustManagerFactorySpi.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.Pair;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Set;
+import javax.net.ssl.ManagerFactoryParameters;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.TrustManagerFactorySpi;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/** @hide */
+public class RootTrustManagerFactorySpi extends TrustManagerFactorySpi {
+    private ApplicationConfig mApplicationConfig;
+    private NetworkSecurityConfig mConfig;
+
+    @Override
+    public void engineInit(ManagerFactoryParameters spec)
+            throws InvalidAlgorithmParameterException {
+        if (!(spec instanceof ApplicationConfigParameters)) {
+            throw new InvalidAlgorithmParameterException("Unsupported spec: " +  spec + ". Only "
+                    + ApplicationConfigParameters.class.getName() + " supported");
+
+        }
+        mApplicationConfig = ((ApplicationConfigParameters) spec).config;
+    }
+
+    @Override
+    public void engineInit(KeyStore ks) throws KeyStoreException {
+        if (ks != null) {
+            mApplicationConfig = new ApplicationConfig(new KeyStoreConfigSource(ks));
+        } else {
+            mApplicationConfig = ApplicationConfig.getDefaultInstance();
+        }
+    }
+
+    @Override
+    public TrustManager[] engineGetTrustManagers() {
+        if (mApplicationConfig == null) {
+            throw new IllegalStateException("TrustManagerFactory not initialized");
+        }
+        return new TrustManager[] { mApplicationConfig.getTrustManager() };
+    }
+
+    @VisibleForTesting
+    public static final class ApplicationConfigParameters implements ManagerFactoryParameters {
+        public final ApplicationConfig config;
+        public ApplicationConfigParameters(ApplicationConfig config) {
+            this.config = config;
+        }
+    }
+}
diff --git a/core/java/android/security/net/config/SystemCertificateSource.java b/core/java/android/security/net/config/SystemCertificateSource.java
new file mode 100644
index 0000000..7649a97
--- /dev/null
+++ b/core/java/android/security/net/config/SystemCertificateSource.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.os.Environment;
+import android.os.UserHandle;
+import android.util.ArraySet;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Set;
+import libcore.io.IoUtils;
+
+/**
+ * {@link CertificateSource} based on the system trusted CA store.
+ * @hide
+ */
+public class SystemCertificateSource implements CertificateSource {
+    private static final SystemCertificateSource INSTANCE = new SystemCertificateSource();
+    private Set<X509Certificate> mSystemCerts = null;
+    private final Object mLock = new Object();
+
+    private SystemCertificateSource() {
+    }
+
+    public static SystemCertificateSource getInstance() {
+        return INSTANCE;
+    }
+
+    @Override
+    public Set<X509Certificate> getCertificates() {
+        // TODO: loading all of these is wasteful, we should instead use a keystore style API.
+        synchronized (mLock) {
+            if (mSystemCerts != null) {
+                return mSystemCerts;
+            }
+            CertificateFactory certFactory;
+            try {
+                certFactory = CertificateFactory.getInstance("X.509");
+            } catch (CertificateException e) {
+                throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e);
+            }
+
+            final String ANDROID_ROOT = System.getenv("ANDROID_ROOT");
+            final File systemCaDir = new File(ANDROID_ROOT + "/etc/security/cacerts");
+            final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
+            final File userRemovedCaDir = new File(configDir, "cacerts-removed");
+            // Sanity check
+            if (!systemCaDir.isDirectory()) {
+                throw new AssertionError(systemCaDir + " is not a directory");
+            }
+
+            Set<X509Certificate> systemCerts = new ArraySet<X509Certificate>();
+            for (String caFile : systemCaDir.list()) {
+                // Skip any CAs in the user's deleted directory.
+                if (new File(userRemovedCaDir, caFile).exists()) {
+                    continue;
+                }
+                InputStream is = null;
+                try {
+                    is = new BufferedInputStream(
+                            new FileInputStream(new File(systemCaDir, caFile)));
+                    systemCerts.add((X509Certificate) certFactory.generateCertificate(is));
+                } catch (CertificateException | IOException e) {
+                    // Don't rethrow to be consistent with conscrypt's cert loading code.
+                    continue;
+                } finally {
+                    IoUtils.closeQuietly(is);
+                }
+            }
+            mSystemCerts = systemCerts;
+            return mSystemCerts;
+        }
+    }
+
+    public void onCertificateStorageChange() {
+        synchronized (mLock) {
+            mSystemCerts = null;
+        }
+    }
+}
diff --git a/core/java/android/security/net/config/TrustAnchor.java b/core/java/android/security/net/config/TrustAnchor.java
new file mode 100644
index 0000000..b62d85f
--- /dev/null
+++ b/core/java/android/security/net/config/TrustAnchor.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import java.security.cert.X509Certificate;
+
+/** @hide */
+public final class TrustAnchor {
+    public final X509Certificate certificate;
+    public final boolean overridesPins;
+
+    public TrustAnchor(X509Certificate certificate, boolean overridesPins) {
+        if (certificate == null) {
+            throw new NullPointerException("certificate");
+        }
+        this.certificate = certificate;
+        this.overridesPins = overridesPins;
+    }
+}
diff --git a/core/java/android/security/net/config/UserCertificateSource.java b/core/java/android/security/net/config/UserCertificateSource.java
new file mode 100644
index 0000000..e9d5aa1
--- /dev/null
+++ b/core/java/android/security/net/config/UserCertificateSource.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.os.Environment;
+import android.os.UserHandle;
+import android.util.ArraySet;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Set;
+import libcore.io.IoUtils;
+
+/**
+ * {@link CertificateSource} based on the user-installed trusted CA store.
+ * @hide
+ */
+public class UserCertificateSource implements CertificateSource {
+    private static final UserCertificateSource INSTANCE = new UserCertificateSource();
+    private Set<X509Certificate> mUserCerts = null;
+    private final Object mLock = new Object();
+
+    private UserCertificateSource() {
+    }
+
+    public static UserCertificateSource getInstance() {
+        return INSTANCE;
+    }
+
+    @Override
+    public Set<X509Certificate> getCertificates() {
+        // TODO: loading all of these is wasteful, we should instead use a keystore style API.
+        synchronized (mLock) {
+            if (mUserCerts != null) {
+                return mUserCerts;
+            }
+            CertificateFactory certFactory;
+            try {
+                certFactory = CertificateFactory.getInstance("X.509");
+            } catch (CertificateException e) {
+                throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e);
+            }
+            final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
+            final File userCaDir = new File(configDir, "cacerts-added");
+            Set<X509Certificate> userCerts = new ArraySet<X509Certificate>();
+            // If the user hasn't added any certificates the directory may not exist.
+            if (userCaDir.isDirectory()) {
+                for (String caFile : userCaDir.list()) {
+                    InputStream is = null;
+                    try {
+                        is = new BufferedInputStream(
+                                new FileInputStream(new File(userCaDir, caFile)));
+                        userCerts.add((X509Certificate) certFactory.generateCertificate(is));
+                    } catch (CertificateException | IOException e) {
+                        // Don't rethrow to be consistent with conscrypt's cert loading code.
+                        continue;
+                    } finally {
+                        IoUtils.closeQuietly(is);
+                    }
+                }
+            }
+            mUserCerts = userCerts;
+            return mUserCerts;
+        }
+    }
+
+    public void onCertificateStorageChange() {
+        synchronized (mLock) {
+            mUserCerts = null;
+        }
+    }
+}
diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java
new file mode 100644
index 0000000..1706e95
--- /dev/null
+++ b/core/java/android/security/net/config/XmlConfigSource.java
@@ -0,0 +1,387 @@
+package android.security.net.config;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.util.ArraySet;
+import android.util.Base64;
+import android.util.Pair;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * {@link ConfigSource} based on an XML configuration file.
+ *
+ * @hide
+ */
+public class XmlConfigSource implements ConfigSource {
+    private static final int CONFIG_BASE = 0;
+    private static final int CONFIG_DOMAIN = 1;
+    private static final int CONFIG_DEBUG = 2;
+
+    private final Object mLock = new Object();
+    private final int mResourceId;
+    private final boolean mDebugBuild;
+
+    private boolean mInitialized;
+    private NetworkSecurityConfig mDefaultConfig;
+    private Set<Pair<Domain, NetworkSecurityConfig>> mDomainMap;
+    private Context mContext;
+
+    public XmlConfigSource(Context context, int resourceId) {
+        this(context, resourceId, false);
+    }
+
+    public XmlConfigSource(Context context, int resourceId, boolean debugBuild) {
+        mResourceId = resourceId;
+        mContext = context;
+        mDebugBuild = debugBuild;
+    }
+
+    public Set<Pair<Domain, NetworkSecurityConfig>> getPerDomainConfigs() {
+        ensureInitialized();
+        return mDomainMap;
+    }
+
+    public NetworkSecurityConfig getDefaultConfig() {
+        ensureInitialized();
+        return mDefaultConfig;
+    }
+
+    private static final String getConfigString(int configType) {
+        switch (configType) {
+            case CONFIG_BASE:
+                return "base-config";
+            case CONFIG_DOMAIN:
+                return "domain-config";
+            case CONFIG_DEBUG:
+                return "debug-overrides";
+            default:
+                throw new IllegalArgumentException("Unknown config type: " + configType);
+        }
+    }
+
+    private void ensureInitialized() {
+        synchronized (mLock) {
+            if (mInitialized) {
+                return;
+            }
+            try (XmlResourceParser parser = mContext.getResources().getXml(mResourceId)) {
+                parseNetworkSecurityConfig(parser);
+                mContext = null;
+                mInitialized = true;
+            } catch (Resources.NotFoundException | XmlPullParserException | IOException
+                    | ParserException e) {
+                throw new RuntimeException("Failed to parse XML configuration from "
+                        + mContext.getResources().getResourceEntryName(mResourceId), e);
+            }
+        }
+    }
+
+    private Pin parsePin(XmlResourceParser parser)
+            throws IOException, XmlPullParserException, ParserException {
+        String digestAlgorithm = parser.getAttributeValue(null, "digest");
+        if (!Pin.isSupportedDigestAlgorithm(digestAlgorithm)) {
+            throw new ParserException(parser, "Unsupported pin digest algorithm: "
+                    + digestAlgorithm);
+        }
+        if (parser.next() != XmlPullParser.TEXT) {
+            throw new ParserException(parser, "Missing pin digest");
+        }
+        String digest = parser.getText();
+        byte[] decodedDigest = null;
+        try {
+            decodedDigest = Base64.decode(digest, 0);
+        } catch (IllegalArgumentException e) {
+            throw new ParserException(parser, "Invalid pin digest", e);
+        }
+        int expectedLength = Pin.getDigestLength(digestAlgorithm);
+        if (decodedDigest.length != expectedLength) {
+            throw new ParserException(parser, "digest length " + decodedDigest.length
+                    + " does not match expected length for " + digestAlgorithm + " of "
+                    + expectedLength);
+        }
+        if (parser.next() != XmlPullParser.END_TAG) {
+            throw new ParserException(parser, "pin contains additional elements");
+        }
+        return new Pin(digestAlgorithm, decodedDigest);
+    }
+
+    private PinSet parsePinSet(XmlResourceParser parser)
+            throws IOException, XmlPullParserException, ParserException {
+        String expirationDate = parser.getAttributeValue(null, "expiration");
+        long expirationTimestampMilis = Long.MAX_VALUE;
+        if (expirationDate != null) {
+            try {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                sdf.setLenient(false);
+                Date date = sdf.parse(expirationDate);
+                if (date == null) {
+                    throw new ParserException(parser, "Invalid expiration date in pin-set");
+                }
+                expirationTimestampMilis = date.getTime();
+            } catch (ParseException e) {
+                throw new ParserException(parser, "Invalid expiration date in pin-set", e);
+            }
+        }
+
+        int outerDepth = parser.getDepth();
+        Set<Pin> pins = new ArraySet<>();
+        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+            String tagName = parser.getName();
+            if (tagName.equals("pin")) {
+                pins.add(parsePin(parser));
+            } else {
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+        return new PinSet(pins, expirationTimestampMilis);
+    }
+
+    private Domain parseDomain(XmlResourceParser parser, Set<String> seenDomains)
+            throws IOException, XmlPullParserException, ParserException {
+        boolean includeSubdomains =
+                parser.getAttributeBooleanValue(null, "includeSubdomains", false);
+        if (parser.next() != XmlPullParser.TEXT) {
+            throw new ParserException(parser, "Domain name missing");
+        }
+        String domain = parser.getText().toLowerCase(Locale.US);
+        if (parser.next() != XmlPullParser.END_TAG) {
+            throw new ParserException(parser, "domain contains additional elements");
+        }
+        // Domains are matched using a most specific match, so don't allow duplicates.
+        // includeSubdomains isn't relevant here, both android.com + subdomains and android.com
+        // match for android.com equally. Do not allow any duplicates period.
+        if (!seenDomains.add(domain)) {
+            throw new ParserException(parser, domain + " has already been specified");
+        }
+        return new Domain(domain, includeSubdomains);
+    }
+
+    private CertificatesEntryRef parseCertificatesEntry(XmlResourceParser parser,
+            boolean defaultOverridePins)
+            throws IOException, XmlPullParserException, ParserException {
+        boolean overridePins =
+                parser.getAttributeBooleanValue(null, "overridePins", defaultOverridePins);
+        int sourceId = parser.getAttributeResourceValue(null, "src", -1);
+        String sourceString = parser.getAttributeValue(null, "src");
+        CertificateSource source = null;
+        if (sourceString == null) {
+            throw new ParserException(parser, "certificates element missing src attribute");
+        }
+        if (sourceId != -1) {
+            // TODO: Cache ResourceCertificateSources by sourceId
+            source = new ResourceCertificateSource(sourceId, mContext);
+        } else if ("system".equals(sourceString)) {
+            source = SystemCertificateSource.getInstance();
+        } else if ("user".equals(sourceString)) {
+            source = UserCertificateSource.getInstance();
+        } else {
+            throw new ParserException(parser, "Unknown certificates src. "
+                    + "Should be one of system|user|@resourceVal");
+        }
+        XmlUtils.skipCurrentTag(parser);
+        return new CertificatesEntryRef(source, overridePins);
+    }
+
+    private Collection<CertificatesEntryRef> parseTrustAnchors(XmlResourceParser parser,
+            boolean defaultOverridePins)
+            throws IOException, XmlPullParserException, ParserException {
+        int outerDepth = parser.getDepth();
+        List<CertificatesEntryRef> anchors = new ArrayList<>();
+        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+            String tagName = parser.getName();
+            if (tagName.equals("certificates")) {
+                anchors.add(parseCertificatesEntry(parser, defaultOverridePins));
+            } else {
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+        return anchors;
+    }
+
+    private List<Pair<NetworkSecurityConfig.Builder, Set<Domain>>> parseConfigEntry(
+            XmlResourceParser parser, Set<String> seenDomains,
+            NetworkSecurityConfig.Builder parentBuilder, int configType)
+            throws IOException, XmlPullParserException, ParserException {
+        List<Pair<NetworkSecurityConfig.Builder, Set<Domain>>> builders = new ArrayList<>();
+        NetworkSecurityConfig.Builder builder = new NetworkSecurityConfig.Builder();
+        builder.setParent(parentBuilder);
+        Set<Domain> domains = new ArraySet<>();
+        boolean seenPinSet = false;
+        boolean seenTrustAnchors = false;
+        boolean defaultOverridePins = configType == CONFIG_DEBUG;
+        String configName = parser.getName();
+        int outerDepth = parser.getDepth();
+        // Add this builder now so that this builder occurs before any of its children. This
+        // makes the final build pass easier.
+        builders.add(new Pair<>(builder, domains));
+        // Parse config attributes. Only set values that are present, config inheritence will
+        // handle the rest.
+        for (int i = 0; i < parser.getAttributeCount(); i++) {
+            String name = parser.getAttributeName(i);
+            if ("hstsEnforced".equals(name)) {
+                builder.setHstsEnforced(
+                        parser.getAttributeBooleanValue(i,
+                                NetworkSecurityConfig.DEFAULT_HSTS_ENFORCED));
+            } else if ("cleartextTrafficPermitted".equals(name)) {
+                builder.setCleartextTrafficPermitted(
+                        parser.getAttributeBooleanValue(i,
+                                NetworkSecurityConfig.DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED));
+            }
+        }
+        // Parse the config elements.
+        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+            String tagName = parser.getName();
+            if ("domain".equals(tagName)) {
+                if (configType != CONFIG_DOMAIN) {
+                    throw new ParserException(parser,
+                            "domain element not allowed in " + getConfigString(configType));
+                }
+                Domain domain = parseDomain(parser, seenDomains);
+                domains.add(domain);
+            } else if ("trust-anchors".equals(tagName)) {
+                if (seenTrustAnchors) {
+                    throw new ParserException(parser,
+                            "Multiple trust-anchor elements not allowed");
+                }
+                builder.addCertificatesEntryRefs(
+                        parseTrustAnchors(parser, defaultOverridePins));
+                seenTrustAnchors = true;
+            } else if ("pin-set".equals(tagName)) {
+                if (configType != CONFIG_DOMAIN) {
+                    throw new ParserException(parser,
+                            "pin-set element not allowed in " + getConfigString(configType));
+                }
+                if (seenPinSet) {
+                    throw new ParserException(parser, "Multiple pin-set elements not allowed");
+                }
+                builder.setPinSet(parsePinSet(parser));
+                seenPinSet = true;
+            } else if ("domain-config".equals(tagName)) {
+                if (configType != CONFIG_DOMAIN) {
+                    throw new ParserException(parser,
+                            "Nested domain-config not allowed in " + getConfigString(configType));
+                }
+                builders.addAll(parseConfigEntry(parser, seenDomains, builder, configType));
+            } else {
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+        if (configType == CONFIG_DOMAIN && domains.isEmpty()) {
+            throw new ParserException(parser, "No domain elements in domain-config");
+        }
+        return builders;
+    }
+
+    private void addDebugAnchorsIfNeeded(NetworkSecurityConfig.Builder debugConfigBuilder,
+            NetworkSecurityConfig.Builder builder) {
+        if (debugConfigBuilder == null || !debugConfigBuilder.hasCertificatesEntryRefs()) {
+            return;
+        }
+        // Don't add trust anchors if not already present, the builder will inherit the anchors
+        // from its parent, and that's where the trust anchors should be added.
+        if (!builder.hasCertificatesEntryRefs()) {
+            return;
+        }
+
+        builder.addCertificatesEntryRefs(debugConfigBuilder.getCertificatesEntryRefs());
+    }
+
+    private void parseNetworkSecurityConfig(XmlResourceParser parser)
+            throws IOException, XmlPullParserException, ParserException {
+        Set<String> seenDomains = new ArraySet<>();
+        List<Pair<NetworkSecurityConfig.Builder, Set<Domain>>> builders = new ArrayList<>();
+        NetworkSecurityConfig.Builder baseConfigBuilder = null;
+        NetworkSecurityConfig.Builder debugConfigBuilder = null;
+        boolean seenDebugOverrides = false;
+        boolean seenBaseConfig = false;
+
+        XmlUtils.beginDocument(parser, "network-security-config");
+        int outerDepth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+            if ("base-config".equals(parser.getName())) {
+                if (seenBaseConfig) {
+                    throw new ParserException(parser, "Only one base-config allowed");
+                }
+                seenBaseConfig = true;
+                baseConfigBuilder =
+                        parseConfigEntry(parser, seenDomains, null, CONFIG_BASE).get(0).first;
+            } else if ("domain-config".equals(parser.getName())) {
+                builders.addAll(
+                        parseConfigEntry(parser, seenDomains, baseConfigBuilder, CONFIG_DOMAIN));
+            } else if ("debug-overrides".equals(parser.getName())) {
+                if (seenDebugOverrides) {
+                    throw new ParserException(parser, "Only one debug-overrides allowed");
+                }
+                if (mDebugBuild) {
+                    debugConfigBuilder =
+                            parseConfigEntry(parser, seenDomains, null, CONFIG_DEBUG).get(0).first;
+                } else {
+                    XmlUtils.skipCurrentTag(parser);
+                }
+                seenDebugOverrides = true;
+            } else {
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+
+        // Use the platform default as the parent of the base config for any values not provided
+        // there. If there is no base config use the platform default.
+        NetworkSecurityConfig.Builder platformDefaultBuilder =
+                NetworkSecurityConfig.getDefaultBuilder();
+        addDebugAnchorsIfNeeded(debugConfigBuilder, platformDefaultBuilder);
+        if (baseConfigBuilder != null) {
+            baseConfigBuilder.setParent(platformDefaultBuilder);
+            addDebugAnchorsIfNeeded(debugConfigBuilder, baseConfigBuilder);
+        } else {
+            baseConfigBuilder = platformDefaultBuilder;
+        }
+        // Build the per-domain config mapping.
+        Set<Pair<Domain, NetworkSecurityConfig>> configs = new ArraySet<>();
+
+        for (Pair<NetworkSecurityConfig.Builder, Set<Domain>> entry : builders) {
+            NetworkSecurityConfig.Builder builder = entry.first;
+            Set<Domain> domains = entry.second;
+            // Set the parent of configs that do not have a parent to the base-config. This can
+            // happen if the base-config comes after a domain-config in the file.
+            // Note that this is safe with regards to children because of the order that
+            // parseConfigEntry returns builders, the parent is always before the children. The
+            // children builders will not have build called until _after_ their parents have their
+            // parent set so everything is consistent.
+            if (builder.getParent() == null) {
+                builder.setParent(baseConfigBuilder);
+            }
+            addDebugAnchorsIfNeeded(debugConfigBuilder, builder);
+            NetworkSecurityConfig config = builder.build();
+            for (Domain domain : domains) {
+                configs.add(new Pair<>(domain, config));
+            }
+        }
+        mDefaultConfig = baseConfigBuilder.build();
+        mDomainMap = configs;
+    }
+
+    public static class ParserException extends Exception {
+
+        public ParserException(XmlPullParser parser, String message, Throwable cause) {
+            super(message + " at: " + parser.getPositionDescription(), cause);
+        }
+
+        public ParserException(XmlPullParser parser, String message) {
+            this(parser, message, null);
+        }
+    }
+}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index d598291..d146e5e 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -270,7 +270,7 @@
             @Override
             public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
                     Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-                    Configuration newConfig) {
+                    Configuration newConfig, Rect backDropRect) {
                 Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED,
                         reportDraw ? 1 : 0, outsets);
                 mCaller.sendMessage(msg);
diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java
index cebb8f0..f099479 100644
--- a/core/java/android/util/PathParser.java
+++ b/core/java/android/util/PathParser.java
@@ -27,21 +27,21 @@
     static final String LOGTAG = PathParser.class.getSimpleName();
 
     /**
-     * @param pathData The string representing a path, the same as "d" string in svg file.
+     * @param pathString The string representing a path, the same as "d" string in svg file.
      * @return the generated Path object.
      */
-    public static Path createPathFromPathData(String pathData) {
-        Path path = new Path();
-        PathDataNode[] nodes = createNodesFromPathData(pathData);
-        if (nodes != null) {
-            try {
-                PathDataNode.nodesToPath(nodes, path);
-            } catch (RuntimeException e) {
-                throw new RuntimeException("Error in parsing " + pathData, e);
-            }
-            return path;
+    public static Path createPathFromPathData(String pathString) {
+        if (pathString == null) {
+            throw new IllegalArgumentException("Path string can not be null.");
         }
-        return null;
+        Path path = new Path();
+        boolean hasValidPathData = nParseStringForPath(path.mNativePath, pathString,
+                pathString.length());
+        if (!hasValidPathData) {
+            throw new IllegalArgumentException("Path string: " + pathString +
+                    " does not contain valid path data");
+        }
+        return path;
     }
 
     /**
@@ -701,4 +701,7 @@
             }
         }
     }
+
+    private static native boolean nParseStringForPath(long pathPtr, String pathString,
+            int stringLength);
 }
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index c2c247e..d563f51 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -17,6 +17,9 @@
 package android.view;
 
 import android.graphics.Rect;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -173,6 +176,7 @@
             // Note: This sort is stable.
             mSequentialFocusComparator.setRoot(root);
             mSequentialFocusComparator.setIsLayoutRtl(root.isLayoutRtl());
+            mSequentialFocusComparator.setFocusables(focusables);
             Collections.sort(focusables, mSequentialFocusComparator);
         } finally {
             mSequentialFocusComparator.recycle();
@@ -598,8 +602,16 @@
                 + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
     }
 
+    private static final boolean isValidId(final int id) {
+        return id != 0 && id != View.NO_ID;
+    }
+
     /**
      * Sorts views according to their visual layout and geometry for default tab order.
+     * If views are part of a focus chain (nextFocusForwardId), then they are all grouped
+     * together. The head of the chain is used to determine the order of the chain and is
+     * first in the order and the tail of the chain is the last in the order. The views
+     * in the middle of the chain can be arbitrary order.
      * This is used for sequential focus traversal.
      */
     private static final class SequentialFocusComparator implements Comparator<View> {
@@ -607,9 +619,15 @@
         private final Rect mSecondRect = new Rect();
         private ViewGroup mRoot;
         private boolean mIsLayoutRtl;
+        private final SparseArray<View> mFocusables = new SparseArray<View>();
+        private final SparseBooleanArray mIsConnectedTo = new SparseBooleanArray();
+        private final ArrayMap<View, View> mHeadsOfChains = new ArrayMap<View, View>();
 
         public void recycle() {
             mRoot = null;
+            mFocusables.clear();
+            mHeadsOfChains.clear();
+            mIsConnectedTo.clear();
         }
 
         public void setRoot(ViewGroup root) {
@@ -620,11 +638,72 @@
             mIsLayoutRtl = b;
         }
 
+        public void setFocusables(ArrayList<View> focusables) {
+            for (int i = focusables.size() - 1; i >= 0; i--) {
+                final View view = focusables.get(i);
+                final int id = view.getId();
+                if (isValidId(id)) {
+                    mFocusables.put(id, view);
+                }
+                final int nextId = view.getNextFocusForwardId();
+                if (isValidId(nextId)) {
+                    mIsConnectedTo.put(nextId, true);
+                }
+            }
+
+            for (int i = focusables.size() - 1; i >= 0; i--) {
+                final View view = focusables.get(i);
+                final int nextId = view.getNextFocusForwardId();
+                if (isValidId(nextId) && !mIsConnectedTo.get(view.getId())) {
+                    setHeadOfChain(view);
+                }
+            }
+        }
+
+        private void setHeadOfChain(View head) {
+            for (View view = head; view != null;
+                    view = mFocusables.get(view.getNextFocusForwardId())) {
+                final View otherHead = mHeadsOfChains.get(view);
+                if (otherHead != null) {
+                    if (otherHead == head) {
+                        return; // This view has already had its head set properly
+                    }
+                    // A hydra -- multi-headed focus chain (e.g. A->C and B->C)
+                    // Use the one we've already chosen instead and reset this chain.
+                    view = head;
+                    head = otherHead;
+                }
+                mHeadsOfChains.put(view, head);
+            }
+        }
+
         public int compare(View first, View second) {
             if (first == second) {
                 return 0;
             }
+            // Order between views within a chain is immaterial -- next/previous is
+            // within a chain is handled elsewhere.
+            View firstHead = mHeadsOfChains.get(first);
+            View secondHead = mHeadsOfChains.get(second);
+            if (firstHead == secondHead && firstHead != null) {
+                if (first == firstHead) {
+                    return -1; // first is the head, it should be first
+                } else if (second == firstHead) {
+                    return 1; // second is the head, it should be first
+                } else if (isValidId(first.getNextFocusForwardId())) {
+                    return -1; // first is not the end of the chain
+                } else {
+                    return 1; // first is end of chain
+                }
+            }
+            if (firstHead != null) {
+                first = firstHead;
+            }
+            if (secondHead != null) {
+                second = secondHead;
+            }
 
+            // First see if they belong to the same focus chain.
             getRect(first, mFirstRect);
             getRect(second, mSecondRect);
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java b/core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl
similarity index 69%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
copy to core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl
index f187178..622b9dd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
+++ b/core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.recents.events.activity;
+package android.view;
 
-import com.android.systemui.recents.events.EventBus;
+import android.view.AppTransitionAnimationSpec;
 
 /**
- * This is sent when the window animation into Recents starts.
+ * A cross-process future to fetch the specifications for app transitions.
+ *
+ * {@hide}
  */
-public class EnterRecentsWindowAnimationStartedEvent extends EventBus.Event {
-    // Simple event
+interface IAppTransitionAnimationSpecsFuture {
+    AppTransitionAnimationSpec[] get();
 }
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index cc4bcb6..9e478c1 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -47,7 +47,7 @@
 
     void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets,
             in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw,
-            in Configuration newConfig);
+            in Configuration newConfig, in Rect backDropFrame);
     void moved(int newX, int newY);
     void dispatchAppVisibility(boolean visible);
     void dispatchGetNewSurface();
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index e8a1e32..7b5f5ab 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.IRemoteCallback;
 import android.view.IApplicationToken;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
 import android.view.IWindowSession;
@@ -140,6 +141,15 @@
     void overridePendingAppTransitionMultiThumb(in AppTransitionAnimationSpec[] specs,
             IRemoteCallback startedCallback, IRemoteCallback finishedCallback, boolean scaleUp);
     void overridePendingAppTransitionInPlace(String packageName, int anim);
+
+    /**
+     * Like overridePendingAppTransitionMultiThumb, but uses a future to supply the specs. This is
+     * used for recents, where generating the thumbnails of the specs takes a non-trivial amount of
+     * time, so we want to move that off the critical path for starting the new activity.
+     */
+    void overridePendingAppTransitionMultiThumbFuture(
+            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback startedCallback,
+            boolean scaleUp);
     void executeAppTransition();
     void setAppStartingWindow(IBinder token, String pkg, int theme,
             in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
@@ -209,6 +219,11 @@
      */
     void cancelTaskWindowTransition(int taskId);
 
+    /**
+     * Cancels the thumbnail transitions for the given task.
+     */
+    void cancelTaskThumbnailTransition(int taskId);
+
     // These can only be called with the SET_ORIENTATION permission.
     /**
      * Update the current screen rotation based on the current state of
@@ -317,4 +332,16 @@
      * @return The frame statistics or null if the window does not exist.
      */
     WindowContentFrameStats getWindowContentFrameStats(IBinder token);
+
+    /**
+     * @return the dock side the current docked stack is at; must be one of the
+     *         WindowManagerGlobal.DOCKED_* values
+     */
+    int getDockedStackSide();
+
+    /**
+     * Sets whether we are currently in a drag resize operation where we are changing the docked
+     * stack size.
+     */
+    void setDockedStackResizing(boolean resizing);
 }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 1be2f95..3fc70cc 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -101,16 +101,24 @@
      *  for the parent window appears. This allows for synchronizing movement of a child
      *  to repainting the contents of the parent.
      *
+     *  "width" and "height" correspond to the width and height members of
+     *  WindowManager.LayoutParams in the {@link #relayout relayout()} case.
+     *  This may differ from the surface buffer size in the
+     *  case of {@link LayoutParams#FLAG_SCALED} and {@link #relayout relayout()}
+     *  must be used with requestedWidth/height if this must be changed.
+     *
      *  @param window The window being modified. Must be attached to a parent window
      *  or this call will fail.
      *  @param x The new x position
      *  @param y The new y position
+     *  @param width The new width
+     *  @param height The new height
      *  @param deferTransactionUntilFrame Frame number from our parent (attached) to
      *  defer this action until.
      *  @param outFrame Rect in which is placed the new position/size on screen.
      */
-    void repositionChild(IWindow childWindow, int x, int y, long deferTransactionUntilFrame,
-            out Rect outFrame);
+    void repositionChild(IWindow childWindow, int left, int top, int right, int bottom,
+            long deferTransactionUntilFrame, out Rect outFrame);
 
     /**
      * If a call to relayout() asked to have the surface destroy deferred,
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index dddea21..589c0dc 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -157,10 +157,10 @@
     long mLastLockTime = 0;
 
     boolean mVisible = false;
-    int mLeft = -1;
-    int mTop = -1;
-    int mWidth = -1;
-    int mHeight = -1;
+    int mWindowSpaceLeft = -1;
+    int mWindowSpaceTop = -1;
+    int mWindowSpaceWidth = -1;
+    int mWindowSpaceHeight = -1;
     int mFormat = -1;
     final Rect mSurfaceFrame = new Rect();
     int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
@@ -445,32 +445,33 @@
         getLocationInWindow(mLocation);
         final boolean creating = mWindow == null;
         final boolean formatChanged = mFormat != mRequestedFormat;
-        final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
+        final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight;
         final boolean visibleChanged = mVisible != mRequestedVisible;
-        final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height;
-        final boolean positionChanged = mLeft != mLocation[0] || mTop != mLocation[1];
+        final boolean layoutSizeChanged = getWidth() != mLayout.width
+                || getHeight() != mLayout.height;
+        final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1];
 
         if (force || creating || formatChanged || sizeChanged || visibleChanged
-            || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded || layoutSizeChanged) {
+            || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
             if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
                     + " format=" + formatChanged + " size=" + sizeChanged
                     + " visible=" + visibleChanged
-                    + " left=" + (mLeft != mLocation[0])
-                    + " top=" + (mTop != mLocation[1]));
+                    + " left=" + (mWindowSpaceLeft != mLocation[0])
+                    + " top=" + (mWindowSpaceTop != mLocation[1]));
 
             try {
                 final boolean visible = mVisible = mRequestedVisible;
-                mLeft = mLocation[0];
-                mTop = mLocation[1];
-                mWidth = myWidth;
-                mHeight = myHeight;
+                mWindowSpaceLeft = mLocation[0];
+                mWindowSpaceTop = mLocation[1];
+                mWindowSpaceWidth = myWidth;
+                mWindowSpaceHeight = myHeight;
                 mFormat = mRequestedFormat;
 
                 // Scaling/Translate window's layout here because mLayout is not used elsewhere.
 
                 // Places the window relative
-                mLayout.x = mLeft;
-                mLayout.y = mTop;
+                mLayout.x = mWindowSpaceLeft;
+                mLayout.y = mWindowSpaceTop;
                 mLayout.width = getWidth();
                 mLayout.height = getHeight();
                 if (mTranslator != null) {
@@ -485,6 +486,14 @@
                               | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                               | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                               ;
+                if (!creating && !force && !mUpdateWindowNeeded) {
+                    mLayout.privateFlags |=
+                            WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
+                } else {
+                    mLayout.privateFlags &=
+                            ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
+                }
+
                 if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
                     mLayout.privateFlags |=
                             WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
@@ -516,7 +525,7 @@
                     if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface);
 
                     relayoutResult = mSession.relayout(
-                        mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
+                        mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight,
                             visible ? VISIBLE : GONE,
                             WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
                             mWinFrame, mOverscanInsets, mContentInsets,
@@ -621,11 +630,19 @@
                 TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
                 " w=" + mLayout.width + " h=" + mLayout.height +
                 ", frame=" + mSurfaceFrame);
-        } else if (positionChanged) { // Only the position has changed
-            mLeft = mLocation[0];
-            mTop = mLocation[1];
+        } else if (positionChanged || layoutSizeChanged) { // Only the position has changed
+            mWindowSpaceLeft = mLocation[0];
+            mWindowSpaceTop = mLocation[1];
+            // For our size changed check, we keep mLayout.width and mLayout.height
+            // in view local space.
+            mLocation[0] = mLayout.width = getWidth();
+            mLocation[1] = mLayout.height = getHeight();
+
+            transformFromViewToWindowSpace(mLocation);
+
             try {
-                mSession.repositionChild(mWindow, mLeft, mTop,
+                mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop,
+                        mLocation[0], mLocation[1],
                         viewRoot != null ? viewRoot.getNextFrameNumber() : -1,
                         mWinFrame);
             } catch (RemoteException ex) {
@@ -668,7 +685,7 @@
         @Override
         public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
                 Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-                Configuration newConfig) {
+                Configuration newConfig, Rect backDropRect) {
             SurfaceView surfaceView = mSurfaceView.get();
             if (surfaceView != null) {
                 if (DEBUG) Log.v(
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c2af9f7..461506b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12968,10 +12968,6 @@
 
             mPrivateFlags |= PFLAG_DIRTY;
 
-            // Release any resources in-case we don't end up drawing again
-            // as anything cached is no longer valid
-            resetDisplayList();
-
             if (invalidateCache) {
                 mPrivateFlags |= PFLAG_INVALIDATED;
                 mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
@@ -18498,21 +18494,29 @@
      * must be an array of two integers. After the method returns, the array
      * contains the x and y location in that order.</p>
      *
-     * @param location an array of two integers in which to hold the coordinates
+     * @param outWindowSpace an array of two integers in which to hold the coordinates
      */
-    public void getLocationInWindow(@Size(2) int[] location) {
-        if (location == null || location.length < 2) {
-            throw new IllegalArgumentException("location must be an array of two integers");
+    public void getLocationInWindow(@Size(2) int[] outWindowSpace) {
+        outWindowSpace[0] = 0;
+        outWindowSpace[1] = 0;
+
+        transformFromViewToWindowSpace(outWindowSpace);
+    }
+
+    void transformFromViewToWindowSpace(@Size(2) int[] inOutLocation) {
+        if (inOutLocation == null || inOutLocation.length < 2) {
+            throw new IllegalArgumentException("inOutLocation must be an array of two integers");
         }
 
         if (mAttachInfo == null) {
             // When the view is not attached to a window, this method does not make sense
-            location[0] = location[1] = 0;
+            inOutLocation[0] = inOutLocation[1] = 0;
             return;
         }
 
-        float[] position = mAttachInfo.mTmpTransformLocation;
-        position[0] = position[1] = 0.0f;
+        float position[] = mAttachInfo.mTmpTransformLocation;
+        position[0] = inOutLocation[0];
+        position[1] = inOutLocation[1];
 
         if (!hasIdentityMatrix()) {
             getMatrix().mapPoints(position);
@@ -18544,8 +18548,8 @@
             position[1] -= vr.mCurScrollY;
         }
 
-        location[0] = (int) (position[0] + 0.5f);
-        location[1] = (int) (position[1] + 0.5f);
+        inOutLocation[0] = (int) (position[0] + 0.5f);
+        inOutLocation[1] = (int) (position[1] + 0.5f);
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index faeb353..fdea1ba 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -287,6 +287,7 @@
     final Rect mPendingStableInsets = new Rect();
     final Rect mPendingContentInsets = new Rect();
     final Rect mPendingOutsets = new Rect();
+    final Rect mPendingBackDropFrame = new Rect();
     final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets
             = new ViewTreeObserver.InternalInsetsInfo();
 
@@ -1553,6 +1554,10 @@
                         frame.height() < desiredWindowHeight && frame.height() != mHeight));
         windowShouldResize |= mDragResizing;
 
+        // 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);
+
         // 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.
@@ -1620,7 +1625,7 @@
                 if (mPendingConfiguration.seq != 0) {
                     if (DEBUG_CONFIGURATION) Log.v(TAG, "Visible with new config: "
                             + mPendingConfiguration);
-                    updateConfiguration(mPendingConfiguration, !mFirst);
+                    updateConfiguration(new Configuration(mPendingConfiguration), !mFirst);
                     mPendingConfiguration.seq = 0;
                 }
 
@@ -1633,6 +1638,8 @@
                 final boolean stableInsetsChanged = !mPendingStableInsets.equals(
                         mAttachInfo.mStableInsets);
                 final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
+                final boolean surfaceSizeChanged = (relayoutResult
+                        & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
                 if (contentInsetsChanged) {
                     mAttachInfo.mContentInsets.set(mPendingContentInsets);
                     if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: "
@@ -1718,10 +1725,20 @@
                             mAttachInfo.mHardwareRenderer.isEnabled()) {
                         mAttachInfo.mHardwareRenderer.destroy();
                     }
-                } else if (surfaceGenerationId != mSurface.getGenerationId() &&
-                        mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
+                } else if ((surfaceGenerationId != mSurface.getGenerationId()
+                        || surfaceSizeChanged)
+                        && mSurfaceHolder == null
+                        && mAttachInfo.mHardwareRenderer != null) {
                     mFullRedrawNeeded = true;
                     try {
+                        // Need to do updateSurface (which leads to CanvasContext::setSurface and
+                        // re-create the EGLSurface) if either the Surface changed (as indicated by
+                        // generation id), or WindowManager changed the surface size. The latter is
+                        // because on some chips, changing the consumer side's BufferQueue size may
+                        // not take effect immediately unless we create a new EGLSurface.
+                        // Note that frame size change doesn't always imply surface size change (eg.
+                        // drag resizing uses fullscreen surface), need to check surfaceSizeChanged
+                        // flag from WindowManager.
                         mAttachInfo.mHardwareRenderer.updateSurface(mSurface);
                     } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
@@ -1733,7 +1750,7 @@
                         & WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING) != 0;
                 if (mDragResizing != dragResizing) {
                     if (dragResizing) {
-                        startDragResizing(frame);
+                        startDragResizing(mPendingBackDropFrame);
                     } else {
                         // We shouldn't come here, but if we come we should end the resize.
                         endDragResizing();
@@ -3269,6 +3286,7 @@
                     mPendingStableInsets.set((Rect) args.arg6);
                     mPendingVisibleInsets.set((Rect) args.arg3);
                     mPendingOutsets.set((Rect) args.arg7);
+                    mPendingBackDropFrame.set((Rect) args.arg8);
 
                     args.recycle();
 
@@ -3294,6 +3312,8 @@
                     mWinFrame.top = t;
                     mWinFrame.bottom = t + h;
 
+                    mPendingBackDropFrame.set(mWinFrame);
+
                     if (mView != null) {
                         forceLayout(mView);
                     }
@@ -5647,18 +5667,19 @@
 
     public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
             Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-            Configuration newConfig) {
+            Configuration newConfig, Rect backDropFrame) {
         if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": frame=" + frame.toShortString()
                 + " contentInsets=" + contentInsets.toShortString()
                 + " visibleInsets=" + visibleInsets.toShortString()
-                + " reportDraw=" + reportDraw);
+                + " reportDraw=" + reportDraw
+                + " backDropFrame=" + backDropFrame);
 
         // Tell all listeners that we are resizing the window so that the chrome can get
         // updated as fast as possible on a separate thread,
         if (mDragResizing) {
             synchronized (mWindowCallbacks) {
                 for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
-                    mWindowCallbacks.get(i).onWindowSizeIsChanging(frame);
+                    mWindowCallbacks.get(i).onWindowSizeIsChanging(backDropFrame);
                 }
             }
         }
@@ -5679,6 +5700,7 @@
         args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets;
         args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
         args.arg7 = sameProcessCall ? new Rect(outsets) : outsets;
+        args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame;
         msg.obj = args;
         mHandler.sendMessage(msg);
     }
@@ -6677,11 +6699,11 @@
         @Override
         public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
                 Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-                Configuration newConfig) {
+                Configuration newConfig, Rect backDropFrame) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchResized(frame, overscanInsets, contentInsets,
-                        visibleInsets, stableInsets, outsets, reportDraw, newConfig);
+                        visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame);
             }
         }
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 92e473d..edf4297 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -50,6 +50,18 @@
  * @see android.content.Context#WINDOW_SERVICE
  */
 public interface WindowManager extends ViewManager {
+
+    /** @hide */
+    int DOCKED_INVALID = -1;
+    /** @hide */
+    int DOCKED_LEFT = 1;
+    /** @hide */
+    int DOCKED_TOP = 2;
+    /** @hide */
+    int DOCKED_RIGHT = 3;
+    /** @hide */
+    int DOCKED_BOTTOM = 4;
+
     /**
      * Exception that is thrown when trying to add view whose
      * {@link LayoutParams} {@link LayoutParams#token}
@@ -1136,6 +1148,16 @@
         public static final int PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT = 0x00001000;
 
         /**
+         * Flag indicating that the x, y, width, and height members should be
+         * ignored (and thus their previous value preserved). For example 
+         * because they are being managed externally through repositionChild.
+         *
+         * {@hide}
+         */
+        public static final int PRIVATE_FLAG_PRESERVE_GEOMETRY = 0x00002000;
+
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index ab99b9e..c08e1b5 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -71,12 +71,17 @@
 
     /**
      * The window is being resized by dragging one of the window corners,
-     * in this case the surface would be fullsreen-sized. The client should
+     * 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;
 
     /**
+     * The window manager has changed the size of the surface from the last call.
+     */
+    public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x10;
+
+    /**
      * Flag for relayout: the client will be later giving
      * internal insets; as a result, the window will not impact other window
      * layouts until the insets are given.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index ee06806..122b83a 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -443,30 +443,18 @@
                     if (DEBUG) {
                         Log.i(TAG, "handleMessage: MSG_UNBIND " + sequence);
                     }
-                    boolean startInput = false;
+                    final boolean startInput;
                     synchronized (mH) {
-                        if (mBindSequence == sequence) {
-                            if (false) {
-                                // XXX the server has already unbound!
-                                if (mCurMethod != null && mCurrentTextBoxAttribute != null) {
-                                    try {
-                                        mCurMethod.finishInput();
-                                    } catch (RemoteException e) {
-                                        Log.w(TAG, "IME died: " + mCurId, e);
-                                    }
-                                }
-                            }
-                            clearBindingLocked();
-                            
-                            // If we were actively using the last input method, then
-                            // we would like to re-connect to the next input method.
-                            if (mServedView != null && mServedView.isFocused()) {
-                                mServedConnecting = true;
-                            }
-                            if (mActive) {
-                                startInput = true;
-                            }
+                        if (mBindSequence != sequence) {
+                            return;
                         }
+                        clearBindingLocked();
+                        // If we were actively using the last input method, then
+                        // we would like to re-connect to the next input method.
+                        if (mServedView != null && mServedView.isFocused()) {
+                            mServedConnecting = true;
+                        }
+                        startInput = mActive;
                     }
                     if (startInput) {
                         startInputInner(null, 0, 0, 0);
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index cb18b49..229011d 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -248,7 +248,7 @@
             Context webViewContext = initialApplication.createPackageContext(
                     sPackageInfo.packageName,
                     Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
-            initialApplication.getAssets().addAssetPath(
+            initialApplication.getAssets().addAssetPathAsSharedLibrary(
                     webViewContext.getApplicationInfo().sourceDir);
             ClassLoader clazzLoader = webViewContext.getClassLoader();
             Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 7e542c9..cbb6109 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -171,7 +171,7 @@
         // Set up year picker view.
         mYearPickerView = (YearPickerView) mAnimator.findViewById(R.id.date_picker_year_picker);
         mYearPickerView.setRange(mMinDate, mMaxDate);
-        mYearPickerView.setDate(mCurrentDate.getTimeInMillis());
+        mYearPickerView.setYear(mCurrentDate.get(Calendar.YEAR));
         mYearPickerView.setOnYearSelectedListener(mOnYearSelectedListener);
 
         // Set up content descriptions.
@@ -267,6 +267,9 @@
 
             // Automatically switch to day picker.
             setCurrentView(VIEW_MONTH_DAY);
+
+            // Switch focus back to the year text.
+            mHeaderYear.requestFocus();
         }
     };
 
@@ -344,7 +347,18 @@
                 mAnimator.announceForAccessibility(mSelectDay);
                 break;
             case VIEW_YEAR:
-                mYearPickerView.setDate(mCurrentDate.getTimeInMillis());
+                final int year = mCurrentDate.get(Calendar.YEAR);
+                mYearPickerView.setYear(year);
+                mYearPickerView.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mYearPickerView.requestFocus();
+                        final View selected = mYearPickerView.getSelectedView();
+                        if (selected != null) {
+                            selected.requestFocus();
+                        }
+                    }
+                });
 
                 if (mCurrentView != viewIndex) {
                     mHeaderMonthDay.setActivated(false);
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 8fe8252..f5840dc 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -287,6 +287,14 @@
         return null;
     }
 
+    SimpleMonthView getView(Object object) {
+        if (object == null) {
+            return null;
+        }
+        final ViewHolder holder = (ViewHolder) object;
+        return holder.calendar;
+    }
+
     private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() {
         @Override
         public void onDayClick(SimpleMonthView view, Calendar day) {
diff --git a/core/java/android/widget/DayPickerViewPager.java b/core/java/android/widget/DayPickerViewPager.java
index bb6e3a4..5f0ae29 100644
--- a/core/java/android/widget/DayPickerViewPager.java
+++ b/core/java/android/widget/DayPickerViewPager.java
@@ -16,12 +16,18 @@
 
 package android.widget;
 
-import com.android.internal.widget.ViewPager;
-
+import android.annotation.Nullable;
 import android.content.Context;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+
+import com.android.internal.util.Predicate;
+import com.android.internal.widget.PagerAdapter;
+import com.android.internal.widget.ViewPager;
 
 import java.util.ArrayList;
 
@@ -134,4 +140,37 @@
 
         mMatchParentChildren.clear();
     }
+
+    @Override
+    protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
+        if (predicate.apply(this)) {
+            return this;
+        }
+
+        // Always try the selected view first.
+        final DayPickerPagerAdapter adapter = (DayPickerPagerAdapter) getAdapter();
+        final SimpleMonthView current = adapter.getView(getCurrent());
+        if (current != childToSkip && current != null) {
+            final View v = current.findViewByPredicate(predicate);
+            if (v != null) {
+                return v;
+            }
+        }
+
+        final int len = getChildCount();
+        for (int i = 0; i < len; i++) {
+            final View child = getChildAt(i);
+
+            if (child != childToSkip && child != current) {
+                final View v = child.findViewByPredicate(predicate);
+
+                if (v != null) {
+                    return v;
+                }
+            }
+        }
+
+        return null;
+    }
+
 }
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index d21a5f7..e31bbe9 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -128,6 +128,15 @@
 
     /** @hide */
     @Override
+    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfoInternal(info);
+        if (isEnabled()) {
+            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT);
+        }
+    }
+
+    /** @hide */
+    @Override
     public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
         switch (action) {
             case AccessibilityNodeInfo.ACTION_SET_TEXT: {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 2fabe33..2983053 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2705,11 +2705,22 @@
             mIsShowingUp = false;
         }
 
-        private class SuggestionInfo {
+        private final class SuggestionInfo {
             int suggestionStart, suggestionEnd; // range of actual suggestion within text
-            SuggestionSpan suggestionSpan; // the SuggestionSpan that this TextView represents
+
+            // the SuggestionSpan that this TextView represents
+            @Nullable
+            SuggestionSpan suggestionSpan;
+
             int suggestionIndex; // the index of this suggestion inside suggestionSpan
-            SpannableStringBuilder text = new SpannableStringBuilder();
+
+            @Nullable
+            final SpannableStringBuilder text = new SpannableStringBuilder();
+
+            void clear() {
+                suggestionSpan = null;
+                text.clear();
+            }
         }
 
         private class SuggestionAdapter extends BaseAdapter {
@@ -2863,9 +2874,11 @@
             return Math.min(positionY, displayMetrics.heightPixels - height);
         }
 
-        @Override
-        public void hide() {
-            super.hide();
+        private void hideWithCleanUp() {
+            for (final SuggestionInfo info : mSuggestionInfos) {
+                info.clear();
+            }
+            hide();
         }
 
         private boolean updateSuggestions() {
@@ -3017,7 +3030,7 @@
                     }
                     mTextView.deleteText_internal(spanUnionStart, spanUnionEnd);
                 }
-                hide();
+                hideWithCleanUp();
                 return;
             }
 
@@ -3025,7 +3038,7 @@
             final int spanEnd = editable.getSpanEnd(suggestionInfo.suggestionSpan);
             if (spanStart < 0 || spanEnd <= spanStart) {
                 // Span has been removed
-                hide();
+                hideWithCleanUp();
                 return;
             }
 
@@ -3100,7 +3113,7 @@
                 mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
             }
 
-            hide();
+            hideWithCleanUp();
         }
     }
 
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index 34a8439..a53df88 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -21,7 +21,6 @@
 import com.android.internal.view.menu.MenuPopupHelper;
 import com.android.internal.view.menu.MenuPresenter;
 import com.android.internal.view.menu.ShowableListMenu;
-import com.android.internal.view.menu.SubMenuBuilder;
 
 import android.annotation.MenuRes;
 import android.content.Context;
@@ -33,35 +32,23 @@
 import android.view.View.OnTouchListener;
 
 /**
- * A PopupMenu displays a {@link Menu} in a modal popup window anchored to a {@link View}.
- * The popup will appear below the anchor view if there is room, or above it if there is not.
- * If the IME is visible the popup will not overlap it until it is touched. Touching outside
- * of the popup will dismiss it.
+ * A PopupMenu displays a {@link Menu} in a modal popup window anchored to a
+ * {@link View}. The popup will appear below the anchor view if there is room,
+ * or above it if there is not. If the IME is visible the popup will not
+ * overlap it until it is touched. Touching outside of the popup will dismiss
+ * it.
  */
-public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback {
+public class PopupMenu {
     private final Context mContext;
     private final MenuBuilder mMenu;
     private final View mAnchor;
     private final MenuPopupHelper mPopup;
-    private final boolean mShowCascadingMenus;
 
     private OnMenuItemClickListener mMenuItemClickListener;
     private OnDismissListener mDismissListener;
     private OnTouchListener mDragListener;
 
     /**
-     * Callback interface used to notify the application that the menu has closed.
-     */
-    public interface OnDismissListener {
-        /**
-         * Called when the associated menu has been dismissed.
-         *
-         * @param menu The PopupMenu that was dismissed.
-         */
-        public void onDismiss(PopupMenu menu);
-    }
-
-    /**
      * Constructor to create a new popup menu with an anchor view.
      *
      * @param context Context the popup menu is running in, through which it
@@ -108,14 +95,40 @@
     public PopupMenu(Context context, View anchor, int gravity, int popupStyleAttr,
             int popupStyleRes) {
         mContext = context;
-        mShowCascadingMenus = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_enableCascadingSubmenus);
-        mMenu = new MenuBuilder(context);
-        mMenu.setCallback(this);
         mAnchor = anchor;
+
+        mMenu = new MenuBuilder(context);
+        mMenu.setCallback(new MenuBuilder.Callback() {
+            @Override
+            public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
+                if (mMenuItemClickListener != null) {
+                    return mMenuItemClickListener.onMenuItemClick(item);
+                }
+                return false;
+            }
+
+            @Override
+            public void onMenuModeChange(MenuBuilder menu) {
+            }
+        });
+
         mPopup = new MenuPopupHelper(context, mMenu, anchor, false, popupStyleAttr, popupStyleRes);
         mPopup.setGravity(gravity);
-        mPopup.setCallback(this);
+        mPopup.setCallback(new MenuPresenter.Callback() {
+            @Override
+            public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+                if (mDismissListener != null) {
+                    mDismissListener.onDismiss(PopupMenu.this);
+                }
+            }
+
+            @Override
+            public boolean onOpenSubMenu(MenuBuilder subMenu) {
+                // The menu presenter will handle opening the submenu itself.
+                // Nothing to do here.
+                return false;
+            }
+        });
     }
 
     /**
@@ -125,7 +138,6 @@
      * the next time the popup is shown.
      *
      * @param gravity the gravity used to align the popup window
-     *
      * @see #getGravity()
      */
     public void setGravity(int gravity) {
@@ -134,7 +146,6 @@
 
     /**
      * @return the gravity used to align the popup window to its anchor view
-     *
      * @see #setGravity(int)
      */
     public int getGravity() {
@@ -146,8 +157,8 @@
      * to implement drag-to-open behavior.
      * <p>
      * When the listener is set on a view, touching that view and dragging
-     * outside of its bounds will open the popup window. Lifting will select the
-     * currently touched list item.
+     * outside of its bounds will open the popup window. Lifting will select
+     * the currently touched list item.
      * <p>
      * Example usage:
      * <pre>
@@ -184,9 +195,10 @@
     }
 
     /**
-     * @return the {@link Menu} associated with this popup. Populate the returned Menu with
-     * items before calling {@link #show()}.
+     * Returns the {@link Menu} associated with this popup. Populate the
+     * returned Menu with items before calling {@link #show()}.
      *
+     * @return the {@link Menu} associated with this popup
      * @see #show()
      * @see #getMenuInflater()
      */
@@ -195,9 +207,8 @@
     }
 
     /**
-     * @return a {@link MenuInflater} that can be used to inflate menu items from XML into the
-     * menu returned by {@link #getMenu()}.
-     *
+     * @return a {@link MenuInflater} that can be used to inflate menu items
+     *         from XML into the menu returned by {@link #getMenu()}
      * @see #getMenu()
      */
     public MenuInflater getMenuInflater() {
@@ -205,8 +216,9 @@
     }
 
     /**
-     * Inflate a menu resource into this PopupMenu. This is equivalent to calling
-     * popupMenu.getMenuInflater().inflate(menuRes, popupMenu.getMenu()).
+     * Inflate a menu resource into this PopupMenu. This is equivalent to
+     * calling {@code popupMenu.getMenuInflater().inflate(menuRes, popupMenu.getMenu())}.
+     *
      * @param menuRes Menu resource to inflate
      */
     public void inflate(@MenuRes int menuRes) {
@@ -215,6 +227,7 @@
 
     /**
      * Show the menu popup anchored to the view specified during construction.
+     *
      * @see #dismiss()
      */
     public void show() {
@@ -223,6 +236,7 @@
 
     /**
      * Dismiss the menu popup.
+     *
      * @see #show()
      */
     public void dismiss() {
@@ -230,68 +244,49 @@
     }
 
     /**
-     * Set a listener that will be notified when the user selects an item from the menu.
+     * Sets a listener that will be notified when the user selects an item from
+     * the menu.
      *
-     * @param listener Listener to notify
+     * @param listener the listener to notify
      */
     public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
         mMenuItemClickListener = listener;
     }
 
     /**
-     * Set a listener that will be notified when this menu is dismissed.
+     * Sets a listener that will be notified when this menu is dismissed.
      *
-     * @param listener Listener to notify
+     * @param listener the listener to notify
      */
     public void setOnDismissListener(OnDismissListener listener) {
         mDismissListener = listener;
     }
 
     /**
-     * @hide
-     */
-    public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
-        if (mMenuItemClickListener != null) {
-            return mMenuItemClickListener.onMenuItemClick(item);
-        }
-        return false;
-    }
-
-    /**
-     * @hide
-     */
-    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
-        if (mDismissListener != null) {
-            mDismissListener.onDismiss(this);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public boolean onOpenSubMenu(MenuBuilder subMenu) {
-        // The menu presenter will handle opening the submenu itself. Nothing to do here.
-        return false;
-    }
-
-    /**
-     * @hide
-     */
-    public void onMenuModeChange(MenuBuilder menu) {
-    }
-
-    /**
-     * Interface responsible for receiving menu item click events if the items themselves
-     * do not have individual item click listeners.
+     * Interface responsible for receiving menu item click events if the items
+     * themselves do not have individual item click listeners.
      */
     public interface OnMenuItemClickListener {
         /**
-         * This method will be invoked when a menu item is clicked if the item itself did
-         * not already handle the event.
+         * This method will be invoked when a menu item is clicked if the item
+         * itself did not already handle the event.
          *
-         * @param item {@link MenuItem} that was clicked
-         * @return <code>true</code> if the event was handled, <code>false</code> otherwise.
+         * @param item the menu item that was clicked
+         * @return {@code true} if the event was handled, {@code false}
+         *         otherwise
          */
-        public boolean onMenuItemClick(MenuItem item);
+        boolean onMenuItemClick(MenuItem item);
+    }
+
+    /**
+     * Callback interface used to notify the application that the menu has closed.
+     */
+    public interface OnDismissListener {
+        /**
+         * Called when the associated menu has been dismissed.
+         *
+         * @param menu the popup menu that was dismissed
+         */
+        void onDismiss(PopupMenu menu);
     }
 }
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index e9325ef..6edce91 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -34,8 +35,10 @@
 import android.util.IntArray;
 import android.util.MathUtils;
 import android.util.StateSet;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewParent;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -61,11 +64,14 @@
     private static final String DEFAULT_TITLE_FORMAT = "MMMMy";
     private static final String DAY_OF_WEEK_FORMAT = "EEEEE";
 
+    private static final int SELECTED_HIGHLIGHT_ALPHA = 0xB0;
+
     private final TextPaint mMonthPaint = new TextPaint();
     private final TextPaint mDayOfWeekPaint = new TextPaint();
     private final TextPaint mDayPaint = new TextPaint();
     private final Paint mDaySelectorPaint = new Paint();
     private final Paint mDayHighlightPaint = new Paint();
+    private final Paint mDayHighlightSelectorPaint = new Paint();
 
     private final Calendar mCalendar = Calendar.getInstance();
     private final Calendar mDayOfWeekLabelCalendar = Calendar.getInstance();
@@ -130,7 +136,9 @@
 
     private ColorStateList mDayTextColor;
 
-    private int mTouchedItem = -1;
+    private int mHighlightedDay = -1;
+    private int mPreviouslyHighlightedDay = -1;
+    private boolean mIsTouchHighlighted = false;
 
     public SimpleMonthView(Context context) {
         this(context, null);
@@ -268,6 +276,9 @@
         mDayHighlightPaint.setAntiAlias(true);
         mDayHighlightPaint.setStyle(Style.FILL);
 
+        mDayHighlightSelectorPaint.setAntiAlias(true);
+        mDayHighlightSelectorPaint.setStyle(Style.FILL);
+
         mDayPaint.setAntiAlias(true);
         mDayPaint.setTextSize(dayTextSize);
         mDayPaint.setTypeface(Typeface.create(dayTypeface, 0));
@@ -296,6 +307,8 @@
         final int activatedColor = dayBackgroundColor.getColorForState(
                 StateSet.get(StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_ACTIVATED), 0);
         mDaySelectorPaint.setColor(activatedColor);
+        mDayHighlightSelectorPaint.setColor(activatedColor);
+        mDayHighlightSelectorPaint.setAlpha(SELECTED_HIGHLIGHT_ALPHA);
         invalidate();
     }
 
@@ -326,8 +339,10 @@
             case MotionEvent.ACTION_DOWN:
             case MotionEvent.ACTION_MOVE:
                 final int touchedItem = getDayAtLocation(x, y);
-                if (mTouchedItem != touchedItem) {
-                    mTouchedItem = touchedItem;
+                mIsTouchHighlighted = true;
+                if (mHighlightedDay != touchedItem) {
+                    mHighlightedDay = touchedItem;
+                    mPreviouslyHighlightedDay = touchedItem;
                     invalidate();
                 }
                 if (action == MotionEvent.ACTION_DOWN && touchedItem < 0) {
@@ -342,7 +357,8 @@
                 // Fall through.
             case MotionEvent.ACTION_CANCEL:
                 // Reset touched day on stream end.
-                mTouchedItem = -1;
+                mHighlightedDay = -1;
+                mIsTouchHighlighted = false;
                 invalidate();
                 break;
         }
@@ -350,6 +366,228 @@
     }
 
     @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        // We need to handle focus change within the SimpleMonthView because we are simulating
+        // multiple Views. The arrow keys will move between days until there is no space (no
+        // day to the left, top, right, or bottom). Focus forward and back jumps out of the
+        // SimpleMonthView, skipping over other SimpleMonthViews in the parent ViewPager
+        // to the next focusable View in the hierarchy.
+        boolean focusChanged = false;
+        switch (event.getKeyCode()) {
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+                if (event.hasNoModifiers()) {
+                    focusChanged = moveOneDay(isLayoutRtl());
+                }
+                break;
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+                if (event.hasNoModifiers()) {
+                    focusChanged = moveOneDay(!isLayoutRtl());
+                }
+                break;
+            case KeyEvent.KEYCODE_DPAD_UP:
+                if (event.hasNoModifiers()) {
+                    ensureFocusedDay();
+                    if (mHighlightedDay > 7) {
+                        mHighlightedDay -= 7;
+                        focusChanged = true;
+                    }
+                }
+                break;
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                if (event.hasNoModifiers()) {
+                    ensureFocusedDay();
+                    if (mHighlightedDay <= mDaysInMonth - 7) {
+                        mHighlightedDay += 7;
+                        focusChanged = true;
+                    }
+                }
+                break;
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_ENTER:
+                if (mHighlightedDay != -1) {
+                    onDayClicked(mHighlightedDay);
+                    return true;
+                }
+                break;
+            case KeyEvent.KEYCODE_TAB: {
+                int focusChangeDirection = 0;
+                if (event.hasNoModifiers()) {
+                    focusChangeDirection = View.FOCUS_FORWARD;
+                } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
+                    focusChangeDirection = View.FOCUS_BACKWARD;
+                }
+                if (focusChangeDirection != 0) {
+                    final ViewParent parent = getParent();
+                    // move out of the ViewPager next/previous
+                    View nextFocus = this;
+                    do {
+                        nextFocus = nextFocus.focusSearch(focusChangeDirection);
+                    } while (nextFocus != null && nextFocus != this &&
+                            nextFocus.getParent() == parent);
+                    if (nextFocus != null) {
+                        nextFocus.requestFocus();
+                        return true;
+                    }
+                }
+                break;
+            }
+        }
+        if (focusChanged) {
+            invalidate();
+            return true;
+        } else {
+            return super.onKeyDown(keyCode, event);
+        }
+    }
+
+    private boolean moveOneDay(boolean positive) {
+        ensureFocusedDay();
+        boolean focusChanged = false;
+        if (positive) {
+            if (!isLastDayOfWeek(mHighlightedDay) && mHighlightedDay < mDaysInMonth) {
+                mHighlightedDay++;
+                focusChanged = true;
+            }
+        } else {
+            if (!isFirstDayOfWeek(mHighlightedDay) && mHighlightedDay > 1) {
+                mHighlightedDay--;
+                focusChanged = true;
+            }
+        }
+        return focusChanged;
+    }
+
+    @Override
+    protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
+            @Nullable Rect previouslyFocusedRect) {
+        if (gainFocus) {
+            // If we've gained focus through arrow keys, we should find the day closest
+            // to the focus rect. If we've gained focus through forward/back, we should
+            // focus on the selected day if there is one.
+            final int offset = findDayOffset();
+            switch(direction) {
+                case View.FOCUS_RIGHT: {
+                    int row = findClosestRow(previouslyFocusedRect);
+                    mHighlightedDay = row == 0 ? 1 : (row * DAYS_IN_WEEK) - offset + 1;
+                    break;
+                }
+                case View.FOCUS_LEFT: {
+                    int row = findClosestRow(previouslyFocusedRect) + 1;
+                    mHighlightedDay = Math.min(mDaysInMonth, (row * DAYS_IN_WEEK) - offset);
+                    break;
+                }
+                case View.FOCUS_DOWN: {
+                    final int col = findClosestColumn(previouslyFocusedRect);
+                    final int day = col - offset + 1;
+                    mHighlightedDay = day < 1 ? day + DAYS_IN_WEEK : day;
+                    break;
+                }
+                case View.FOCUS_UP: {
+                    final int col = findClosestColumn(previouslyFocusedRect);
+                    final int maxWeeks = (offset + mDaysInMonth) / DAYS_IN_WEEK;
+                    final int day = col - offset + (DAYS_IN_WEEK * maxWeeks) + 1;
+                    mHighlightedDay = day > mDaysInMonth ? day - DAYS_IN_WEEK : day;
+                    break;
+                }
+            }
+            ensureFocusedDay();
+            invalidate();
+        }
+        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+    }
+
+    /**
+     * Returns the row (0 indexed) closest to previouslyFocusedRect or center if null.
+     */
+    private int findClosestRow(@Nullable Rect previouslyFocusedRect) {
+        if (previouslyFocusedRect == null) {
+            return 3;
+        } else {
+            int centerY = previouslyFocusedRect.centerY();
+
+            final TextPaint p = mDayPaint;
+            final int headerHeight = mMonthHeight + mDayOfWeekHeight;
+            final int rowHeight = mDayHeight;
+
+            // Text is vertically centered within the row height.
+            final float halfLineHeight = (p.ascent() + p.descent()) / 2f;
+            final int rowCenter = headerHeight + rowHeight / 2;
+
+            centerY -= rowCenter - halfLineHeight;
+            int row = Math.round(centerY / (float) rowHeight);
+            final int maxDay = findDayOffset() + mDaysInMonth;
+            final int maxRows = (maxDay / DAYS_IN_WEEK) - ((maxDay % DAYS_IN_WEEK == 0) ? 1 : 0);
+
+            row = MathUtils.constrain(row, 0, maxRows);
+            return row;
+        }
+    }
+
+    /**
+     * Returns the column (0 indexed) closest to the previouslyFocusedRect or center if null.
+     * The 0 index is related to the first day of the week.
+     */
+    private int findClosestColumn(@Nullable Rect previouslyFocusedRect) {
+        if (previouslyFocusedRect == null) {
+            return DAYS_IN_WEEK / 2;
+        } else {
+            int centerX = previouslyFocusedRect.centerX() - mPaddingLeft;
+            final int columnFromLeft =
+                    MathUtils.constrain(centerX / mCellWidth, 0, DAYS_IN_WEEK - 1);
+            return isLayoutRtl() ? DAYS_IN_WEEK - columnFromLeft - 1: columnFromLeft;
+        }
+    }
+
+    @Override
+    public void getFocusedRect(Rect r) {
+        if (mHighlightedDay > 0) {
+            getBoundsForDay(mHighlightedDay, r);
+        } else {
+            super.getFocusedRect(r);
+        }
+    }
+
+    @Override
+    protected void onFocusLost() {
+        if (!mIsTouchHighlighted) {
+            // Unhighlight a day.
+            mPreviouslyHighlightedDay = mHighlightedDay;
+            mHighlightedDay = -1;
+            invalidate();
+        }
+        super.onFocusLost();
+    }
+
+    /**
+     * Ensure some day is highlighted. If a day isn't highlighted, it chooses the selected day,
+     * if possible, or the first day of the month if not.
+     */
+    private void ensureFocusedDay() {
+        if (mHighlightedDay != -1) {
+            return;
+        }
+        if (mPreviouslyHighlightedDay != -1) {
+            mHighlightedDay = mPreviouslyHighlightedDay;
+            return;
+        }
+        if (mActivatedDay != -1) {
+            mHighlightedDay = mActivatedDay;
+            return;
+        }
+        mHighlightedDay = 1;
+    }
+
+    private boolean isFirstDayOfWeek(int day) {
+        final int offset = findDayOffset();
+        return (offset + day - 1) % DAYS_IN_WEEK == 0;
+    }
+
+    private boolean isLastDayOfWeek(int day) {
+        final int offset = findDayOffset();
+        return (offset + day) % DAYS_IN_WEEK == 0;
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         final int paddingLeft = getPaddingLeft();
         final int paddingTop = getPaddingTop();
@@ -432,12 +670,15 @@
             }
 
             final boolean isDayActivated = mActivatedDay == day;
+            final boolean isDayHighlighted = mHighlightedDay == day;
             if (isDayActivated) {
                 stateMask |= StateSet.VIEW_STATE_ACTIVATED;
 
                 // Adjust the circle to be centered on the row.
-                canvas.drawCircle(colCenterRtl, rowCenter, mDaySelectorRadius, mDaySelectorPaint);
-            } else if (mTouchedItem == day) {
+                final Paint paint = isDayHighlighted ? mDayHighlightSelectorPaint :
+                        mDaySelectorPaint;
+                canvas.drawCircle(colCenterRtl, rowCenter, mDaySelectorRadius, paint);
+            } else if (isDayHighlighted) {
                 stateMask |= StateSet.VIEW_STATE_PRESSED;
 
                 if (isDayEnabled) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 13b1c4b..b5d994d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -310,6 +310,14 @@
      */
     static final int PROCESS_TEXT_REQUEST_CODE = 100;
 
+    /**
+     *  Return code of {@link #doKeyDown}.
+     */
+    private static final int KEY_EVENT_NOT_HANDLED = 0;
+    private static final int KEY_EVENT_HANDLED = -1;
+    private static final int KEY_DOWN_HANDLED_BY_KEY_LISTENER = 1;
+    private static final int KEY_DOWN_HANDLED_BY_MOVEMENT_METHOD = 2;
+
     // System wide time for last cut, copy or text changed action.
     static long sLastCutCopyOrTextChangedTime;
 
@@ -3967,6 +3975,15 @@
         }
 
         ((Editable) mText).append(text, start, end);
+
+        if (mAutoLinkMask != 0) {
+            boolean linksWereAdded = Linkify.addLinks((Spannable) mText, mAutoLinkMask);
+            // Do not change the movement method for text that support text selection as it
+            // would prevent an arbitrary cursor displacement.
+            if (linksWereAdded && mLinksClickable && !textCanBeSelected()) {
+                setMovementMethod(LinkMovementMethod.getInstance());
+            }
+        }
     }
 
     private void updateTextColors() {
@@ -5955,8 +5972,8 @@
 
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-        int which = doKeyDown(keyCode, event, null);
-        if (which == 0) {
+        final int which = doKeyDown(keyCode, event, null);
+        if (which == KEY_EVENT_NOT_HANDLED) {
             return super.onKeyDown(keyCode, event);
         }
 
@@ -5966,13 +5983,12 @@
     @Override
     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
         KeyEvent down = KeyEvent.changeAction(event, KeyEvent.ACTION_DOWN);
-
-        int which = doKeyDown(keyCode, down, event);
-        if (which == 0) {
+        final int which = doKeyDown(keyCode, down, event);
+        if (which == KEY_EVENT_NOT_HANDLED) {
             // Go through default dispatching.
             return super.onKeyMultiple(keyCode, repeatCount, event);
         }
-        if (which == -1) {
+        if (which == KEY_EVENT_HANDLED) {
             // Consumed the whole thing.
             return true;
         }
@@ -5985,7 +6001,7 @@
         // It would be nice if those interfaces had an onKeyMultiple() method,
         // but adding that is a more complicated change.
         KeyEvent up = KeyEvent.changeAction(event, KeyEvent.ACTION_UP);
-        if (which == 1) {
+        if (which == KEY_DOWN_HANDLED_BY_KEY_LISTENER) {
             // mEditor and mEditor.mInput are not null from doKeyDown
             mEditor.mKeyListener.onKeyUp(this, (Editable)mText, keyCode, up);
             while (--repeatCount > 0) {
@@ -5994,7 +6010,7 @@
             }
             hideErrorIfUnchanged();
 
-        } else if (which == 2) {
+        } else if (which == KEY_DOWN_HANDLED_BY_MOVEMENT_METHOD) {
             // mMovement is not null from doKeyDown
             mMovement.onKeyUp(this, (Spannable)mText, keyCode, up);
             while (--repeatCount > 0) {
@@ -6051,7 +6067,7 @@
 
     private int doKeyDown(int keyCode, KeyEvent event, KeyEvent otherEvent) {
         if (!isEnabled()) {
-            return 0;
+            return KEY_EVENT_NOT_HANDLED;
         }
 
         // If this is the initial keydown, we don't want to prevent a movement away from this view.
@@ -6078,7 +6094,7 @@
                                 this, EditorInfo.IME_NULL, event)) {
                             mEditor.mInputContentType.enterDown = true;
                             // We are consuming the enter key for them.
-                            return -1;
+                            return KEY_EVENT_HANDLED;
                         }
                     }
 
@@ -6088,9 +6104,9 @@
                     if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0
                             || shouldAdvanceFocusOnEnter()) {
                         if (hasOnClickListeners()) {
-                            return 0;
+                            return KEY_EVENT_NOT_HANDLED;
                         }
-                        return -1;
+                        return KEY_EVENT_HANDLED;
                     }
                 }
                 break;
@@ -6098,7 +6114,7 @@
             case KeyEvent.KEYCODE_DPAD_CENTER:
                 if (event.hasNoModifiers()) {
                     if (shouldAdvanceFocusOnEnter()) {
-                        return 0;
+                        return KEY_EVENT_NOT_HANDLED;
                     }
                 }
                 break;
@@ -6106,7 +6122,7 @@
             case KeyEvent.KEYCODE_TAB:
                 if (event.hasNoModifiers() || event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
                     if (shouldAdvanceFocusOnTab()) {
-                        return 0;
+                        return KEY_EVENT_NOT_HANDLED;
                     }
                 }
                 break;
@@ -6115,7 +6131,31 @@
             case KeyEvent.KEYCODE_BACK:
                 if (mEditor != null && mEditor.mTextActionMode != null) {
                     stopTextActionMode();
-                    return -1;
+                    return KEY_EVENT_HANDLED;
+                }
+                break;
+
+            case KeyEvent.KEYCODE_CUT:
+                if (event.hasNoModifiers() && canCut()) {
+                    if (onTextContextMenuItem(ID_CUT)) {
+                        return KEY_EVENT_HANDLED;
+                    }
+                }
+                break;
+
+            case KeyEvent.KEYCODE_COPY:
+                if (event.hasNoModifiers() && canCopy()) {
+                    if (onTextContextMenuItem(ID_COPY)) {
+                        return KEY_EVENT_HANDLED;
+                    }
+                }
+                break;
+
+            case KeyEvent.KEYCODE_PASTE:
+                if (event.hasNoModifiers() && canPaste()) {
+                    if (onTextContextMenuItem(ID_PASTE)) {
+                        return KEY_EVENT_HANDLED;
+                    }
                 }
                 break;
         }
@@ -6130,7 +6170,7 @@
                     hideErrorIfUnchanged();
                     doDown = false;
                     if (handled) {
-                        return -1;
+                        return KEY_EVENT_HANDLED;
                     }
                 } catch (AbstractMethodError e) {
                     // onKeyOther was added after 1.0, so if it isn't
@@ -6146,7 +6186,7 @@
                         keyCode, event);
                 endBatchEdit();
                 hideErrorIfUnchanged();
-                if (handled) return 1;
+                if (handled) return KEY_DOWN_HANDLED_BY_KEY_LISTENER;
             }
         }
 
@@ -6161,7 +6201,7 @@
                             otherEvent);
                     doDown = false;
                     if (handled) {
-                        return -1;
+                        return KEY_EVENT_HANDLED;
                     }
                 } catch (AbstractMethodError e) {
                     // onKeyOther was added after 1.0, so if it isn't
@@ -6173,12 +6213,13 @@
                     if (event.getRepeatCount() == 0 && !KeyEvent.isModifierKey(keyCode)) {
                         mPreventDefaultMovement = true;
                     }
-                    return 2;
+                    return KEY_DOWN_HANDLED_BY_MOVEMENT_METHOD;
                 }
             }
         }
 
-        return mPreventDefaultMovement && !KeyEvent.isModifierKey(keyCode) ? -1 : 0;
+        return mPreventDefaultMovement && !KeyEvent.isModifierKey(keyCode) ?
+                KEY_EVENT_HANDLED : KEY_EVENT_NOT_HANDLED;
     }
 
     /**
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 8e5af79..a24d37f 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -100,7 +100,7 @@
      * @see #getHour()
      */
     public void setHour(int hour) {
-        mDelegate.setCurrentHour(hour);
+        mDelegate.setHour(hour);
     }
 
     /**
@@ -110,7 +110,7 @@
      * @see #setHour(int)
      */
     public int getHour() {
-        return mDelegate.getCurrentHour();
+        return mDelegate.getHour();
     }
 
     /**
@@ -120,7 +120,7 @@
      * @see #getMinute()
      */
     public void setMinute(int minute) {
-        mDelegate.setCurrentMinute(minute);
+        mDelegate.setMinute(minute);
     }
 
     /**
@@ -130,7 +130,7 @@
      * @see #setMinute(int)
      */
     public int getMinute() {
-        return mDelegate.getCurrentMinute();
+        return mDelegate.getMinute();
     }
 
     /**
@@ -150,7 +150,7 @@
     @NonNull
     @Deprecated
     public Integer getCurrentHour() {
-        return mDelegate.getCurrentHour();
+        return mDelegate.getHour();
     }
 
     /**
@@ -160,7 +160,7 @@
      */
     @Deprecated
     public void setCurrentMinute(@NonNull Integer currentMinute) {
-        mDelegate.setCurrentMinute(currentMinute);
+        mDelegate.setMinute(currentMinute);
     }
 
     /**
@@ -170,7 +170,7 @@
     @NonNull
     @Deprecated
     public Integer getCurrentMinute() {
-        return mDelegate.getCurrentMinute();
+        return mDelegate.getMinute();
     }
 
     /**
@@ -186,7 +186,7 @@
             return;
         }
 
-        mDelegate.setIs24HourView(is24HourView);
+        mDelegate.setIs24Hour(is24HourView);
     }
 
     /**
@@ -195,7 +195,7 @@
      * @see #setIs24HourView(Boolean)
      */
     public boolean is24HourView() {
-        return mDelegate.is24HourView();
+        return mDelegate.is24Hour();
     }
 
     /**
@@ -207,16 +207,6 @@
         mDelegate.setOnTimeChangedListener(onTimeChangedListener);
     }
 
-    /**
-     * Sets the callback that indicates the current time is valid.
-     *
-     * @param callback the callback, may be null
-     * @hide
-     */
-    public void setValidationCallback(@Nullable ValidationCallback callback) {
-        mDelegate.setValidationCallback(callback);
-    }
-
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
@@ -234,12 +224,6 @@
     }
 
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        mDelegate.onConfigurationChanged(newConfig);
-    }
-
-    @Override
     protected Parcelable onSaveInstanceState() {
         Parcelable superState = super.onSaveInstanceState();
         return mDelegate.onSaveInstanceState(superState);
@@ -269,25 +253,22 @@
      * for the real behavior.
      */
     interface TimePickerDelegate {
-        void setCurrentHour(int currentHour);
-        int getCurrentHour();
+        void setHour(int hour);
+        int getHour();
 
-        void setCurrentMinute(int currentMinute);
-        int getCurrentMinute();
+        void setMinute(int minute);
+        int getMinute();
 
-        void setIs24HourView(boolean is24HourView);
-        boolean is24HourView();
+        void setIs24Hour(boolean is24Hour);
+        boolean is24Hour();
 
         void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
-        void setValidationCallback(ValidationCallback callback);
 
         void setEnabled(boolean enabled);
         boolean isEnabled();
 
         int getBaseline();
 
-        void onConfigurationChanged(Configuration newConfig);
-
         Parcelable onSaveInstanceState(Parcelable superState);
         void onRestoreInstanceState(Parcelable state);
 
@@ -295,16 +276,6 @@
         void onPopulateAccessibilityEvent(AccessibilityEvent event);
     }
 
-    /**
-     * A callback interface for updating input validity when the TimePicker
-     * when included into a Dialog.
-     *
-     * @hide
-     */
-    public static interface ValidationCallback {
-        void onValidationChanged(boolean valid);
-    }
-
     static String[] getAmPmStrings(Context context) {
         final Locale locale = context.getResources().getConfiguration().locale;
         final LocaleData d = LocaleData.get(locale);
@@ -319,43 +290,16 @@
      * An abstract class which can be used as a start for TimePicker implementations
      */
     abstract static class AbstractTimePickerDelegate implements TimePickerDelegate {
-        // The delegator
-        protected TimePicker mDelegator;
+        protected final TimePicker mDelegator;
+        protected final Context mContext;
+        protected final Locale mLocale;
 
-        // The context
-        protected Context mContext;
-
-        // The current locale
-        protected Locale mCurrentLocale;
-
-        // Callbacks
         protected OnTimeChangedListener mOnTimeChangedListener;
-        protected ValidationCallback mValidationCallback;
 
-        public AbstractTimePickerDelegate(TimePicker delegator, Context context) {
+        public AbstractTimePickerDelegate(@NonNull TimePicker delegator, @NonNull Context context) {
             mDelegator = delegator;
             mContext = context;
-
-            // initialization based on locale
-            setCurrentLocale(Locale.getDefault());
-        }
-
-        public void setCurrentLocale(Locale locale) {
-            if (locale.equals(mCurrentLocale)) {
-                return;
-            }
-            mCurrentLocale = locale;
-        }
-
-        @Override
-        public void setValidationCallback(ValidationCallback callback) {
-            mValidationCallback = callback;
-        }
-
-        protected void onValidationChanged(boolean valid) {
-            if (mValidationCallback != null) {
-                mValidationCallback.onValidationChanged(valid);
-            }
+            mLocale = context.getResources().getConfiguration().locale;
         }
     }
 }
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index 4dc5fd3e..38ce033 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -19,7 +19,6 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.os.Parcel;
@@ -89,7 +88,7 @@
     private boolean mAllowAutoAdvance;
     private int mInitialHourOfDay;
     private int mInitialMinute;
-    private boolean mIs24HourView;
+    private boolean mIs24Hour;
     private boolean mIsAmPmAtStart;
 
     // Accessibility strings.
@@ -200,19 +199,19 @@
         mAllowAutoAdvance = true;
 
         // Updates mHourFormat variables used below.
-        updateHourFormat(mCurrentLocale, mIs24HourView);
+        updateHourFormat(mLocale, mIs24Hour);
 
         // Update hour text field.
         final int minHour = mHourFormatStartsAtZero ? 0 : 1;
-        final int maxHour = (mIs24HourView ? 23 : 11) + minHour;
+        final int maxHour = (mIs24Hour ? 23 : 11) + minHour;
         mHourView.setRange(minHour, maxHour);
         mHourView.setShowLeadingZeroes(mHourFormatShowLeadingZero);
 
         // Initialize with current time.
-        mTempCalendar = Calendar.getInstance(mCurrentLocale);
+        mTempCalendar = Calendar.getInstance(mLocale);
         final int currentHour = mTempCalendar.get(Calendar.HOUR_OF_DAY);
         final int currentMinute = mTempCalendar.get(Calendar.MINUTE);
-        initialize(currentHour, currentMinute, mIs24HourView, HOUR_INDEX);
+        initialize(currentHour, currentMinute, mIs24Hour, HOUR_INDEX);
     }
 
     /**
@@ -333,7 +332,7 @@
     private void initialize(int hourOfDay, int minute, boolean is24HourView, int index) {
         mInitialHourOfDay = hourOfDay;
         mInitialMinute = minute;
-        mIs24HourView = is24HourView;
+        mIs24Hour = is24HourView;
         updateUI(index);
     }
 
@@ -352,17 +351,16 @@
     }
 
     private void updateRadialPicker(int index) {
-        mRadialTimePickerView.initialize(mInitialHourOfDay, mInitialMinute, mIs24HourView);
+        mRadialTimePickerView.initialize(mInitialHourOfDay, mInitialMinute, mIs24Hour);
         setCurrentItemShowing(index, false, true);
     }
 
     private void updateHeaderAmPm() {
-
-        if (mIs24HourView) {
+        if (mIs24Hour) {
             mAmPmLayout.setVisibility(View.GONE);
         } else {
             // Ensure that AM/PM layout is in the correct position.
-            final String dateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, "hm");
+            final String dateTimePattern = DateFormat.getBestDateTimePattern(mLocale, "hm");
             final boolean isAmPmAtStart = dateTimePattern.startsWith("a");
             setAmPmAtStart(isAmPmAtStart);
 
@@ -395,35 +393,32 @@
      * Set the current hour.
      */
     @Override
-    public void setCurrentHour(int currentHour) {
-        if (mInitialHourOfDay == currentHour) {
-            return;
+    public void setHour(int hour) {
+        if (mInitialHourOfDay != hour) {
+            mInitialHourOfDay = hour;
+            updateHeaderHour(hour, true);
+            updateHeaderAmPm();
+            mRadialTimePickerView.setCurrentHour(hour);
+            mRadialTimePickerView.setAmOrPm(mInitialHourOfDay < 12 ? AM : PM);
+            mDelegator.invalidate();
+            onTimeChanged();
         }
-        mInitialHourOfDay = currentHour;
-        updateHeaderHour(currentHour, true);
-        updateHeaderAmPm();
-        mRadialTimePickerView.setCurrentHour(currentHour);
-        mRadialTimePickerView.setAmOrPm(mInitialHourOfDay < 12 ? AM : PM);
-        mDelegator.invalidate();
-        onTimeChanged();
     }
 
     /**
-     * @return The current hour in the range (0-23).
+     * @return the current hour in the range (0-23)
      */
     @Override
-    public int getCurrentHour() {
-        int currentHour = mRadialTimePickerView.getCurrentHour();
-        if (mIs24HourView) {
+    public int getHour() {
+        final int currentHour = mRadialTimePickerView.getCurrentHour();
+        if (mIs24Hour) {
             return currentHour;
+        }
+
+        if (mRadialTimePickerView.getAmOrPm() == PM) {
+            return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
         } else {
-            switch(mRadialTimePickerView.getAmOrPm()) {
-                case PM:
-                    return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
-                case AM:
-                default:
-                    return currentHour % HOURS_IN_HALF_DAY;
-            }
+            return currentHour % HOURS_IN_HALF_DAY;
         }
     }
 
@@ -431,48 +426,48 @@
      * Set the current minute (0-59).
      */
     @Override
-    public void setCurrentMinute(int currentMinute) {
-        if (mInitialMinute == currentMinute) {
-            return;
+    public void setMinute(int minute) {
+        if (mInitialMinute != minute) {
+            mInitialMinute = minute;
+            updateHeaderMinute(minute, true);
+            mRadialTimePickerView.setCurrentMinute(minute);
+            mDelegator.invalidate();
+            onTimeChanged();
         }
-        mInitialMinute = currentMinute;
-        updateHeaderMinute(currentMinute, true);
-        mRadialTimePickerView.setCurrentMinute(currentMinute);
-        mDelegator.invalidate();
-        onTimeChanged();
     }
 
     /**
      * @return The current minute.
      */
     @Override
-    public int getCurrentMinute() {
+    public int getMinute() {
         return mRadialTimePickerView.getCurrentMinute();
     }
 
     /**
-     * Set whether in 24 hour or AM/PM mode.
+     * Sets whether time is displayed in 24-hour mode or 12-hour mode with
+     * AM/PM indicators.
      *
-     * @param is24HourView True = 24 hour mode. False = AM/PM.
+     * @param is24Hour {@code true} to display time in 24-hour mode or
+     *        {@code false} for 12-hour mode with AM/PM
      */
-    @Override
-    public void setIs24HourView(boolean is24HourView) {
-        if (is24HourView == mIs24HourView) {
-            return;
+    public void setIs24Hour(boolean is24Hour) {
+        if (mIs24Hour != is24Hour) {
+            mIs24Hour = is24Hour;
+            mInitialHourOfDay = getHour();
+
+            updateUI(mRadialTimePickerView.getCurrentItemShowing());
         }
-
-        mIs24HourView = is24HourView;
-        mInitialHourOfDay = getCurrentHour();
-
-        updateUI(mRadialTimePickerView.getCurrentItemShowing());
     }
 
     /**
-     * @return true if this is in 24 hour view else false.
+     * @return {@code true} if time is displayed in 24-hour mode, or
+     *         {@code false} if time is displayed in 12-hour mode with AM/PM
+     *         indicators
      */
     @Override
-    public boolean is24HourView() {
-        return mIs24HourView;
+    public boolean is24Hour() {
+        return mIs24Hour;
     }
 
     @Override
@@ -502,14 +497,9 @@
     }
 
     @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        updateUI(mRadialTimePickerView.getCurrentItemShowing());
-    }
-
-    @Override
     public Parcelable onSaveInstanceState(Parcelable superState) {
-        return new SavedState(superState, getCurrentHour(), getCurrentMinute(),
-                is24HourView(), getCurrentItemShowing());
+        return new SavedState(superState, getHour(), getMinute(),
+                is24Hour(), getCurrentItemShowing());
     }
 
     @Override
@@ -520,12 +510,6 @@
     }
 
     @Override
-    public void setCurrentLocale(Locale locale) {
-        super.setCurrentLocale(locale);
-        mTempCalendar = Calendar.getInstance(locale);
-    }
-
-    @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
         onPopulateAccessibilityEvent(event);
         return true;
@@ -534,13 +518,13 @@
     @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
         int flags = DateUtils.FORMAT_SHOW_TIME;
-        if (mIs24HourView) {
+        if (mIs24Hour) {
             flags |= DateUtils.FORMAT_24HOUR;
         } else {
             flags |= DateUtils.FORMAT_12HOUR;
         }
-        mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour());
-        mTempCalendar.set(Calendar.MINUTE, getCurrentMinute());
+        mTempCalendar.set(Calendar.HOUR_OF_DAY, getHour());
+        mTempCalendar.set(Calendar.MINUTE, getMinute());
         String selectedDate = DateUtils.formatDateTime(mContext,
                 mTempCalendar.getTimeInMillis(), flags);
         event.getText().add(selectedDate);
@@ -559,8 +543,7 @@
     private void onTimeChanged() {
         mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
         if (mOnTimeChangedListener != null) {
-            mOnTimeChangedListener.onTimeChanged(mDelegator,
-                    getCurrentHour(), getCurrentMinute());
+            mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute());
         }
     }
 
@@ -666,7 +649,7 @@
         }
 
         if (mOnTimeChangedListener != null) {
-            mOnTimeChangedListener.onTimeChanged(mDelegator, getCurrentHour(), getCurrentMinute());
+            mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute());
         }
     }
 
@@ -677,14 +660,14 @@
      * @return a localized hour number
      */
     private int getLocalizedHour(int hourOfDay) {
-        if (!mIs24HourView) {
+        if (!mIs24Hour) {
             // Convert to hour-of-am-pm.
             hourOfDay %= 12;
         }
 
         if (!mHourFormatStartsAtZero && hourOfDay == 0) {
             // Convert to clock-hour (either of-day or of-am-pm).
-            hourOfDay = mIs24HourView ? 24 : 12;
+            hourOfDay = mIs24Hour ? 24 : 12;
         }
 
         return hourOfDay;
@@ -716,8 +699,8 @@
      * separator as the character which is just after the hour marker in the returned pattern.
      */
     private void updateHeaderSeparator() {
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
-                (mIs24HourView) ? "Hm" : "hm");
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mLocale,
+                (mIs24Hour) ? "Hm" : "hm");
         final String separatorText;
         // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats
         final char[] hourFormats = {'H', 'h', 'K', 'k'};
@@ -819,14 +802,14 @@
     private final Runnable mCommitHour = new Runnable() {
         @Override
         public void run() {
-            setCurrentHour(mHourView.getValue());
+            setHour(mHourView.getValue());
         }
     };
 
     private final Runnable mCommitMinute = new Runnable() {
         @Override
         public void run() {
-            setCurrentMinute(mMinuteView.getValue());
+            setMinute(mMinuteView.getValue());
         }
     };
 
diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java
index 8741cc3..2ed230b 100644
--- a/core/java/android/widget/TimePickerSpinnerDelegate.java
+++ b/core/java/android/widget/TimePickerSpinnerDelegate.java
@@ -17,7 +17,6 @@
 package android.widget;
 
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -33,7 +32,6 @@
 import com.android.internal.R;
 
 import java.util.Calendar;
-import java.util.Locale;
 
 import libcore.icu.LocaleData;
 
@@ -92,7 +90,7 @@
         mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
             public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
                 updateInputState();
-                if (!is24HourView()) {
+                if (!is24Hour()) {
                     if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) ||
                             (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) {
                         mIsAm = !mIsAm;
@@ -124,14 +122,14 @@
                 int maxValue = mMinuteSpinner.getMaxValue();
                 if (oldVal == maxValue && newVal == minValue) {
                     int newHour = mHourSpinner.getValue() + 1;
-                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) {
+                    if (!is24Hour() && newHour == HOURS_IN_HALF_DAY) {
                         mIsAm = !mIsAm;
                         updateAmPmControl();
                     }
                     mHourSpinner.setValue(newHour);
                 } else if (oldVal == minValue && newVal == maxValue) {
                     int newHour = mHourSpinner.getValue() - 1;
-                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) {
+                    if (!is24Hour() && newHour == HOURS_IN_HALF_DAY - 1) {
                         mIsAm = !mIsAm;
                         updateAmPmControl();
                     }
@@ -204,8 +202,8 @@
         updateAmPmControl();
 
         // set to current time
-        setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
-        setCurrentMinute(mTempCalendar.get(Calendar.MINUTE));
+        setHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
+        setMinute(mTempCalendar.get(Calendar.MINUTE));
 
         if (!isEnabled()) {
             setEnabled(false);
@@ -221,7 +219,7 @@
     }
 
     private void getHourFormatData() {
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mLocale,
                 (mIs24HourView) ? "Hm" : "hm");
         final int lengthPattern = bestDateTimePattern.length();
         mHourWithTwoDigit = false;
@@ -241,7 +239,7 @@
     }
 
     private boolean isAmPmAtStart() {
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mLocale,
                 "hm" /* skeleton */);
 
         return bestDateTimePattern.startsWith("a");
@@ -257,7 +255,7 @@
      */
     private void setDividerText() {
         final String skeleton = (mIs24HourView) ? "Hm" : "hm";
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mLocale,
                 skeleton);
         final String separatorText;
         int hourIndex = bestDateTimePattern.lastIndexOf('H');
@@ -279,16 +277,16 @@
     }
 
     @Override
-    public void setCurrentHour(int currentHour) {
-        setCurrentHour(currentHour, true);
+    public void setHour(int hour) {
+        setCurrentHour(hour, true);
     }
 
     private void setCurrentHour(int currentHour, boolean notifyTimeChanged) {
         // why was Integer used in the first place?
-        if (currentHour == getCurrentHour()) {
+        if (currentHour == getHour()) {
             return;
         }
-        if (!is24HourView()) {
+        if (!is24Hour()) {
             // convert [0,23] ordinal to wall clock display
             if (currentHour >= HOURS_IN_HALF_DAY) {
                 mIsAm = false;
@@ -310,9 +308,9 @@
     }
 
     @Override
-    public int getCurrentHour() {
+    public int getHour() {
         int currentHour = mHourSpinner.getValue();
-        if (is24HourView()) {
+        if (is24Hour()) {
             return currentHour;
         } else if (mIsAm) {
             return currentHour % HOURS_IN_HALF_DAY;
@@ -322,28 +320,27 @@
     }
 
     @Override
-    public void setCurrentMinute(int currentMinute) {
-        if (currentMinute == getCurrentMinute()) {
+    public void setMinute(int minute) {
+        if (minute == getMinute()) {
             return;
         }
-        mMinuteSpinner.setValue(currentMinute);
+        mMinuteSpinner.setValue(minute);
         onTimeChanged();
     }
 
     @Override
-    public int getCurrentMinute() {
+    public int getMinute() {
         return mMinuteSpinner.getValue();
     }
 
-    @Override
-    public void setIs24HourView(boolean is24HourView) {
-        if (mIs24HourView == is24HourView) {
+    public void setIs24Hour(boolean is24Hour) {
+        if (mIs24HourView == is24Hour) {
             return;
         }
         // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!!
-        int currentHour = getCurrentHour();
+        int currentHour = getHour();
         // Order is important here.
-        mIs24HourView = is24HourView;
+        mIs24HourView = is24Hour;
         getHourFormatData();
         updateHourControl();
         // set value after spinner range is updated
@@ -353,7 +350,7 @@
     }
 
     @Override
-    public boolean is24HourView() {
+    public boolean is24Hour() {
         return mIs24HourView;
     }
 
@@ -388,20 +385,15 @@
     }
 
     @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        setCurrentLocale(newConfig.locale);
-    }
-
-    @Override
     public Parcelable onSaveInstanceState(Parcelable superState) {
-        return new SavedState(superState, getCurrentHour(), getCurrentMinute());
+        return new SavedState(superState, getHour(), getMinute());
     }
 
     @Override
     public void onRestoreInstanceState(Parcelable state) {
         SavedState ss = (SavedState) state;
-        setCurrentHour(ss.getHour());
-        setCurrentMinute(ss.getMinute());
+        setHour(ss.getHour());
+        setMinute(ss.getMinute());
     }
 
     @Override
@@ -418,8 +410,8 @@
         } else {
             flags |= DateUtils.FORMAT_12HOUR;
         }
-        mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour());
-        mTempCalendar.set(Calendar.MINUTE, getCurrentMinute());
+        mTempCalendar.set(Calendar.HOUR_OF_DAY, getHour());
+        mTempCalendar.set(Calendar.MINUTE, getMinute());
         String selectedDateUtterance = DateUtils.formatDateTime(mContext,
                 mTempCalendar.getTimeInMillis(), flags);
         event.getText().add(selectedDateUtterance);
@@ -447,7 +439,7 @@
     }
 
     private void updateAmPmControl() {
-        if (is24HourView()) {
+        if (is24Hour()) {
             if (mAmPmSpinner != null) {
                 mAmPmSpinner.setVisibility(View.GONE);
             } else {
@@ -466,27 +458,16 @@
         mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
     }
 
-    /**
-     * Sets the current locale.
-     *
-     * @param locale The current locale.
-     */
-    @Override
-    public void setCurrentLocale(Locale locale) {
-        super.setCurrentLocale(locale);
-        mTempCalendar = Calendar.getInstance(locale);
-    }
-
     private void onTimeChanged() {
         mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
         if (mOnTimeChangedListener != null) {
-            mOnTimeChangedListener.onTimeChanged(mDelegator, getCurrentHour(),
-                    getCurrentMinute());
+            mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(),
+                    getMinute());
         }
     }
 
     private void updateHourControl() {
-        if (is24HourView()) {
+        if (is24Hour()) {
             // 'k' means 1-24 hour
             if (mHourFormat == 'k') {
                 mHourSpinner.setMinValue(1);
@@ -509,7 +490,7 @@
     }
 
     private void updateMinuteControl() {
-        if (is24HourView()) {
+        if (is24Hour()) {
             mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
         } else {
             mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java
index 89e59f9..96624d2 100644
--- a/core/java/android/widget/YearPickerView.java
+++ b/core/java/android/widget/YearPickerView.java
@@ -38,8 +38,6 @@
 
     private OnYearSelectedListener mOnYearSelectedListener;
 
-    private long mCurrentTimeMillis;
-
     public YearPickerView(Context context, AttributeSet attrs) {
         this(context, attrs, R.attr.listViewStyle);
     }
@@ -79,10 +77,6 @@
         mOnYearSelectedListener = listener;
     }
 
-    public void setDate(long currentTimeMillis) {
-        mCurrentTimeMillis = currentTimeMillis;
-    }
-
     /**
      * Sets the currently selected year. Jumps immediately to the new year.
      *
diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java
index e26b27d..c067da7 100644
--- a/core/java/com/android/internal/os/BaseCommand.java
+++ b/core/java/com/android/internal/os/BaseCommand.java
@@ -17,13 +17,19 @@
 
 package com.android.internal.os;
 
+import android.os.ShellCommand;
+
 import java.io.PrintStream;
 
 public abstract class BaseCommand {
 
-    protected String[] mArgs;
-    private int mNextArg;
-    private String mCurArgData;
+    final protected ShellCommand mArgs = new ShellCommand() {
+        @Override public int onCommand(String cmd) {
+            return 0;
+        }
+        @Override public void onHelp() {
+        }
+    };
 
     // These are magic strings understood by the Eclipse plugin.
     public static final String FATAL_ERROR_CODE = "Error type 1";
@@ -39,9 +45,7 @@
             return;
         }
 
-        mArgs = args;
-        mNextArg = 0;
-        mCurArgData = null;
+        mArgs.init(null, null, null, null, args, 0);
 
         try {
             onRun();
@@ -87,32 +91,7 @@
      * starts with '-'.  If the next argument is not an option, null is returned.
      */
     public String nextOption() {
-        if (mCurArgData != null) {
-            String prev = mArgs[mNextArg - 1];
-            throw new IllegalArgumentException("No argument expected after \"" + prev + "\"");
-        }
-        if (mNextArg >= mArgs.length) {
-            return null;
-        }
-        String arg = mArgs[mNextArg];
-        if (!arg.startsWith("-")) {
-            return null;
-        }
-        mNextArg++;
-        if (arg.equals("--")) {
-            return null;
-        }
-        if (arg.length() > 1 && arg.charAt(1) != '-') {
-            if (arg.length() > 2) {
-                mCurArgData = arg.substring(2);
-                return arg.substring(0, 2);
-            } else {
-                mCurArgData = null;
-                return arg;
-            }
-        }
-        mCurArgData = null;
-        return arg;
+        return mArgs.getNextOption();
     }
 
     /**
@@ -120,15 +99,7 @@
      * no arguments left, return null.
      */
     public String nextArg() {
-        if (mCurArgData != null) {
-            String arg = mCurArgData;
-            mCurArgData = null;
-            return arg;
-        } else if (mNextArg < mArgs.length) {
-            return mArgs[mNextArg++];
-        } else {
-            return null;
-        }
+        return mArgs.getNextArg();
     }
 
     /**
@@ -136,11 +107,6 @@
      * no arguments left, throws an IllegalArgumentException to report this to the user.
      */
     public String nextArgRequired() {
-        String arg = nextArg();
-        if (arg == null) {
-            String prev = mArgs[mNextArg - 1];
-            throw new IllegalArgumentException("Argument expected after \"" + prev + "\"");
-        }
-        return arg;
+        return mArgs.getNextArgRequired();
     }
 }
diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java
index c05e0d8..8fb56d4 100644
--- a/core/java/com/android/internal/os/SomeArgs.java
+++ b/core/java/com/android/internal/os/SomeArgs.java
@@ -47,6 +47,7 @@
     public Object arg5;
     public Object arg6;
     public Object arg7;
+    public Object arg8;
     public int argi1;
     public int argi2;
     public int argi3;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9a5cde6..f78d8d8 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -523,7 +523,7 @@
         String args[] = {
             "--setuid=1000",
             "--setgid=1000",
-            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
+            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009",
             "--capabilities=" + capabilities + "," + capabilities,
             "--nice-name=system_server",
             "--runtime-args",
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 1bce585..83f810f 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2404,7 +2404,7 @@
 
         private PhoneWindow mWindow;
 
-        public DecorView(Context context, int featureId) {
+        private DecorView(Context context, int featureId, PhoneWindow window) {
             super(context);
             mFeatureId = featureId;
 
@@ -2415,6 +2415,8 @@
 
             mBarEnterExitDuration = context.getResources().getInteger(
                     R.integer.dock_enter_exit_duration);
+
+            setWindow(window);
         }
 
         public void setBackgroundFallback(int resId) {
@@ -3868,22 +3870,7 @@
                 context.setTheme(mTheme);
             }
         }
-        return new DecorView(context, featureId);
-    }
-
-    protected void setFeatureFromAttrs(int featureId, TypedArray attrs,
-            int drawableAttr, int alphaAttr) {
-        Drawable d = attrs.getDrawable(drawableAttr);
-        if (d != null) {
-            requestFeature(featureId);
-            setFeatureDefaultDrawable(featureId, d);
-        }
-        if ((getFeatures() & (1 << featureId)) != 0) {
-            int alpha = attrs.getInt(alphaAttr, -1);
-            if (alpha >= 0) {
-                setFeatureDrawableAlpha(featureId, alpha);
-            }
-        }
+        return new DecorView(context, featureId, this);
     }
 
     protected ViewGroup generateLayout(DecorView decor) {
@@ -4268,7 +4255,6 @@
         mForceDecorInstall = false;
         if (mDecor == null) {
             mDecor = generateDecor(-1);
-            mDecor.setWindow(this);
             mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
             mDecor.setIsRootNamespace(true);
             if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index f190d8c..e8970bc 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -144,6 +144,13 @@
     }
 
     /**
+     * Checks if given array is null or has zero elements.
+     */
+    public static boolean isEmpty(byte[] array) {
+        return array == null || array.length == 0;
+    }
+
+    /**
      * Checks that value is present as at least one of the elements of the array.
      * @param array the array to check in
      * @param value the value to check for
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 07bfce7..8699843 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -35,7 +35,8 @@
 
     @Override
     public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
-            Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig) {
+            Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig,
+            Rect backDropFrame) {
         if (reportDraw) {
             try {
                 mSession.finishDrawing(this);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 60ef4a4..889c7b3 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -126,6 +126,8 @@
     private static final String LOCK_SCREEN_OWNER_INFO_ENABLED =
             Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
 
+    private static final String LOCK_SCREEN_DEVICE_OWNER_INFO = "lockscreen.device_owner_info";
+
     private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
 
     // Maximum allowed number of repeated or ordered characters in a sequence before we'll
@@ -578,6 +580,29 @@
     }
 
     /**
+     * Sets the device owner information. If the information is {@code null} or empty then the
+     * device owner info is cleared.
+     *
+     * @param info Device owner information which will be displayed instead of the user
+     * owner info.
+     */
+    public void setDeviceOwnerInfo(String info) {
+        if (info != null && info.isEmpty()) {
+            info = null;
+        }
+
+        setString(LOCK_SCREEN_DEVICE_OWNER_INFO, info, UserHandle.USER_SYSTEM);
+    }
+
+    public String getDeviceOwnerInfo() {
+        return getString(LOCK_SCREEN_DEVICE_OWNER_INFO, UserHandle.USER_SYSTEM);
+    }
+
+    public boolean isDeviceOwnerInfoEnabled() {
+        return getDeviceOwnerInfo() != null;
+    }
+
+    /**
      * Compute the password quality from the given password string.
      */
     static public int computePasswordQuality(String password) {
diff --git a/core/java/com/android/internal/widget/NonClientDecorView.java b/core/java/com/android/internal/widget/NonClientDecorView.java
index de542b1..de6e228 100644
--- a/core/java/com/android/internal/widget/NonClientDecorView.java
+++ b/core/java/com/android/internal/widget/NonClientDecorView.java
@@ -372,7 +372,7 @@
     @Override
     public void onRequestDraw(boolean reportNextDraw) {
         if (mFrameRendererThread != null) {
-            mFrameRendererThread.onRequsetDraw(reportNextDraw);
+            mFrameRendererThread.onRequestDraw(reportNextDraw);
         } else if (reportNextDraw) {
             // If render thread is gone, just report immediately.
             if (isAttachedToWindow()) {
@@ -517,7 +517,12 @@
         public void run() {
             try {
                 Looper.prepare();
-                mChoreographer = Choreographer.getInstance();
+                synchronized (this) {
+                    mChoreographer = Choreographer.getInstance();
+
+                    // Draw at least once.
+                    mChoreographer.postFrameCallback(this);
+                }
                 Looper.loop();
             } finally {
                 releaseRenderer();
@@ -580,7 +585,7 @@
             }
         }
 
-        public void onRequsetDraw(boolean reportNextDraw) {
+        public void onRequestDraw(boolean reportNextDraw) {
             synchronized (this) {
                 mReportNextDraw = reportNextDraw;
                 mOldTargetRect.set(0, 0, 0, 0);
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 6217d6e..948a6bb 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -1095,7 +1095,16 @@
                     View child = getChildAt(i);
                     ii = infoForChild(child);
                     if (ii != null && ii.position == mCurItem) {
-                        if (child.requestFocus(focusDirection)) {
+                        final Rect focusRect;
+                        if (currentFocused == null) {
+                            focusRect = null;
+                        } else {
+                            focusRect = mTempRect;
+                            currentFocused.getFocusedRect(mTempRect);
+                            offsetDescendantRectToMyCoords(currentFocused, mTempRect);
+                            offsetRectIntoDescendantCoords(child, mTempRect);
+                        }
+                        if (child.requestFocus(focusDirection, focusRect)) {
                             break;
                         }
                     }
@@ -1321,6 +1330,11 @@
         }
     }
 
+    public Object getCurrent() {
+        final ItemInfo itemInfo = infoForPosition(getCurrentItem());
+        return itemInfo == null ? null : itemInfo.object;
+    }
+
     @Override
     public void removeView(View view) {
         if (mInLayout) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 7b69c9e..4d648ce 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -89,6 +89,7 @@
     android_util_Binder.cpp \
     android_util_EventLog.cpp \
     android_util_Log.cpp \
+    android_util_PathParser.cpp \
     android_util_Process.cpp \
     android_util_StringBlock.cpp \
     android_util_XmlBlock.cpp \
@@ -271,7 +272,7 @@
 
 # -Wno-c++11-extensions: Clang warns about Skia using the C++11 override keyword, but this project
 #                        is not being compiled with that level. Remove once this has changed.
-LOCAL_CFLAGS += -Wno-c++11-extensions
+LOCAL_CLANG_CFLAGS += -Wno-c++11-extensions
 
 # b/22414716: thread_local (android/graphics/Paint.cpp) and Clang don't like each other at the
 #             moment.
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index ffc69a9..815d330 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -110,6 +110,7 @@
 extern int register_android_content_AssetManager(JNIEnv* env);
 extern int register_android_util_EventLog(JNIEnv* env);
 extern int register_android_util_Log(JNIEnv* env);
+extern int register_android_util_PathParser(JNIEnv* env);
 extern int register_android_content_StringBlock(JNIEnv* env);
 extern int register_android_content_XmlBlock(JNIEnv* env);
 extern int register_android_graphics_Canvas(JNIEnv* env);
@@ -888,21 +889,22 @@
                        profileMaxStackDepth,
                        "-Xprofile-max-stack-depth:");
 
-    /*
-     * Tracing options.
-     */
-    property_get("dalvik.vm.method-trace", propBuf, "false");
-    if (strcmp(propBuf, "true") == 0) {
-        addOption("-Xmethod-trace");
-        parseRuntimeOption("dalvik.vm.method-trace-file",
-                           methodTraceFileBuf,
-                           "-Xmethod-trace-file:");
-        parseRuntimeOption("dalvik.vm.method-trace-file-siz",
-                           methodTraceFileSizeBuf,
-                           "-Xmethod-trace-file-size:");
-        property_get("dalvik.vm.method-trace-stream", propBuf, "false");
+    // Trace files are stored in /data/misc/trace which is writable only in debug mode.
+    property_get("ro.debuggable", propBuf, "0");
+    if (strcmp(propBuf, "1") == 0) {
+        property_get("dalvik.vm.method-trace", propBuf, "false");
         if (strcmp(propBuf, "true") == 0) {
-            addOption("-Xmethod-trace-stream");
+            addOption("-Xmethod-trace");
+            parseRuntimeOption("dalvik.vm.method-trace-file",
+                               methodTraceFileBuf,
+                               "-Xmethod-trace-file:");
+            parseRuntimeOption("dalvik.vm.method-trace-file-siz",
+                               methodTraceFileSizeBuf,
+                               "-Xmethod-trace-file-size:");
+            property_get("dalvik.vm.method-trace-stream", propBuf, "false");
+            if (strcmp(propBuf, "true") == 0) {
+                addOption("-Xmethod-trace-stream");
+            }
         }
     }
 
@@ -1299,6 +1301,7 @@
     REG_JNI(register_android_os_SystemClock),
     REG_JNI(register_android_util_EventLog),
     REG_JNI(register_android_util_Log),
+    REG_JNI(register_android_util_PathParser),
     REG_JNI(register_android_content_AssetManager),
     REG_JNI(register_android_content_StringBlock),
     REG_JNI(register_android_content_XmlBlock),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 703a9bd..a805b6d 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -1006,6 +1006,7 @@
         // is disposed.
         int dupFd = dup(blob.fd());
         if (dupFd < 0) {
+            ALOGE("Error allocating dup fd. Error:%d", errno);
             blob.release();
             SkSafeUnref(ctable);
             doThrowRE(env, "Could not allocate dup blob fd.");
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 2df3a46..3cdf640 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -39,14 +39,14 @@
 
 using namespace android;
 
-class SkBitmapRegionDecoder {
+class BitmapRegionDecoder {
 public:
-    SkBitmapRegionDecoder(SkImageDecoder* decoder, int width, int height) {
+    BitmapRegionDecoder(SkImageDecoder* decoder, int width, int height) {
         fDecoder = decoder;
         fWidth = width;
         fHeight = height;
     }
-    ~SkBitmapRegionDecoder() {
+    ~BitmapRegionDecoder() {
         delete fDecoder;
     }
 
@@ -91,7 +91,7 @@
         return nullObjectReturn("decoder->buildTileIndex returned false");
     }
 
-    SkBitmapRegionDecoder *bm = new SkBitmapRegionDecoder(decoder, width, height);
+    BitmapRegionDecoder *bm = new BitmapRegionDecoder(decoder, width, height);
     return GraphicsJNI::createBitmapRegionDecoder(env, bm);
 }
 
@@ -166,7 +166,7 @@
  */
 static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle,
                                 jint start_x, jint start_y, jint width, jint height, jobject options) {
-    SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+    BitmapRegionDecoder *brd = reinterpret_cast<BitmapRegionDecoder*>(brdHandle);
     jobject tileBitmap = NULL;
     SkImageDecoder *decoder = brd->getDecoder();
     int sampleSize = 1;
@@ -245,17 +245,17 @@
 }
 
 static jint nativeGetHeight(JNIEnv* env, jobject, jlong brdHandle) {
-    SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+    BitmapRegionDecoder *brd = reinterpret_cast<BitmapRegionDecoder*>(brdHandle);
     return static_cast<jint>(brd->getHeight());
 }
 
 static jint nativeGetWidth(JNIEnv* env, jobject, jlong brdHandle) {
-    SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+    BitmapRegionDecoder *brd = reinterpret_cast<BitmapRegionDecoder*>(brdHandle);
     return static_cast<jint>(brd->getWidth());
 }
 
 static void nativeClean(JNIEnv* env, jobject, jlong brdHandle) {
-    SkBitmapRegionDecoder *brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
+    BitmapRegionDecoder *brd = reinterpret_cast<BitmapRegionDecoder*>(brdHandle);
     delete brd;
 }
 
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 068517a..ed44019 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -439,7 +439,7 @@
     return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID);
 }
 
-jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap)
+jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, BitmapRegionDecoder* bitmap)
 {
     SkASSERT(bitmap != NULL);
 
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index bcd834b..90f8291 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -12,7 +12,7 @@
 #include <Canvas.h>
 #include <jni.h>
 
-class SkBitmapRegionDecoder;
+class BitmapRegionDecoder;
 class SkCanvas;
 
 namespace android {
@@ -90,7 +90,7 @@
 
     static jobject createRegion(JNIEnv* env, SkRegion* region);
 
-    static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
+    static jobject createBitmapRegionDecoder(JNIEnv* env, BitmapRegionDecoder* bitmap);
 
     static android::Bitmap* allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
             SkColorTable* ctable);
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
index b9dd77a..ec6471e 100644
--- a/core/jni/android_hardware_Radio.cpp
+++ b/core/jni/android_hardware_Radio.cpp
@@ -93,6 +93,7 @@
     jfieldID mRds;
     jfieldID mTa;
     jfieldID mAf;
+    jfieldID mEa;
 } gRadioFmBandConfigFields;
 
 static const char* const kRadioAmBandConfigClassPathName =
@@ -117,6 +118,7 @@
     jmethodID putIntFromNative;
     jmethodID putStringFromNative;
     jmethodID putBitmapFromNative;
+    jmethodID putClockFromNative;
 } gRadioMetadataMethods;
 
 static Mutex gLock;
@@ -171,7 +173,8 @@
                                       nBandconfig->band.fm.stereo,
                                       nBandconfig->band.fm.rds != RADIO_RDS_NONE,
                                       nBandconfig->band.fm.ta,
-                                      nBandconfig->band.fm.af);
+                                      nBandconfig->band.fm.af,
+                                      nBandconfig->band.fm.ea);
     } else if (nBandconfig->band.type == RADIO_BAND_AM) {
         *jBandDescriptor = env->NewObject(gRadioAmBandDescriptorClass, gRadioAmBandDescriptorCstor,
                                       nBandconfig->region, nBandconfig->band.type,
@@ -205,7 +208,8 @@
                                       nBandconfig->band.fm.stereo,
                                       nBandconfig->band.fm.rds != RADIO_RDS_NONE,
                                       nBandconfig->band.fm.ta,
-                                      nBandconfig->band.fm.af);
+                                      nBandconfig->band.fm.af,
+                                      nBandconfig->band.fm.ea);
     } else if (nBandconfig->band.type == RADIO_BAND_AM) {
         *jBandConfig = env->NewObject(gRadioAmBandConfigClass, gRadioAmBandConfigCstor,
                                       nBandconfig->region, nBandconfig->band.type,
@@ -284,6 +288,18 @@
                 }
                 env->DeleteLocalRef(jData);
             } break;
+            case RADIO_METADATA_TYPE_CLOCK: {
+                  ALOGV("%s RADIO_METADATA_TYPE_CLOCK %d", __FUNCTION__, key);
+                  radio_metadata_clock_t *clock = (radio_metadata_clock_t *) value;
+                  jStatus =
+                      env->CallIntMethod(*jMetadata,
+                                         gRadioMetadataMethods.putClockFromNative,
+                                         key, (jint) clock->utc_seconds_since_epoch,
+                                         (jint) clock->timezone_offset_in_minutes);
+                  if (jStatus == 0) {
+                      jCount++;
+                  }
+            } break;
         }
     }
     return jCount;
@@ -351,6 +367,7 @@
                                      nBandconfig->region);
         nBandconfig->band.fm.ta = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mTa);
         nBandconfig->band.fm.af = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mAf);
+        nBandconfig->band.fm.ea = env->GetBooleanField(jBandConfig, gRadioFmBandConfigFields.mEa);
     } else if (env->IsInstanceOf(jBandConfig, gRadioAmBandConfigClass)) {
         nBandconfig->band.am.stereo =
                 env->GetBooleanField(jBandConfig, gRadioAmBandConfigFields.mStereo);
@@ -518,6 +535,7 @@
             break;
         case RADIO_EVENT_ANTENNA:
         case RADIO_EVENT_TA:
+        case RADIO_EVENT_EA:
         case RADIO_EVENT_CONTROL:
             jArg2 = event->on ? 1 : 0;
             break;
@@ -878,7 +896,7 @@
     jclass fmBandDescriptorClass = FindClassOrDie(env, kRadioFmBandDescriptorClassPathName);
     gRadioFmBandDescriptorClass = MakeGlobalRefOrDie(env, fmBandDescriptorClass);
     gRadioFmBandDescriptorCstor = GetMethodIDOrDie(env, fmBandDescriptorClass, "<init>",
-            "(IIIIIZZZZ)V");
+            "(IIIIIZZZZZ)V");
 
     jclass amBandDescriptorClass = FindClassOrDie(env, kRadioAmBandDescriptorClassPathName);
     gRadioAmBandDescriptorClass = MakeGlobalRefOrDie(env, amBandDescriptorClass);
@@ -894,11 +912,13 @@
     jclass fmBandConfigClass = FindClassOrDie(env, kRadioFmBandConfigClassPathName);
     gRadioFmBandConfigClass = MakeGlobalRefOrDie(env, fmBandConfigClass);
     gRadioFmBandConfigCstor = GetMethodIDOrDie(env, fmBandConfigClass, "<init>",
-            "(IIIIIZZZZ)V");
+            "(IIIIIZZZZZ)V");
     gRadioFmBandConfigFields.mStereo = GetFieldIDOrDie(env, fmBandConfigClass, "mStereo", "Z");
     gRadioFmBandConfigFields.mRds = GetFieldIDOrDie(env, fmBandConfigClass, "mRds", "Z");
     gRadioFmBandConfigFields.mTa = GetFieldIDOrDie(env, fmBandConfigClass, "mTa", "Z");
     gRadioFmBandConfigFields.mAf = GetFieldIDOrDie(env, fmBandConfigClass, "mAf", "Z");
+    gRadioFmBandConfigFields.mEa =
+        GetFieldIDOrDie(env, fmBandConfigClass, "mEa", "Z");
 
 
     jclass amBandConfigClass = FindClassOrDie(env, kRadioAmBandConfigClassPathName);
@@ -924,6 +944,9 @@
     gRadioMetadataMethods.putBitmapFromNative = GetMethodIDOrDie(env, metadataClass,
                                                                  "putBitmapFromNative",
                                                                  "(I[B)I");
+    gRadioMetadataMethods.putClockFromNative = GetMethodIDOrDie(env, metadataClass,
+                                                                "putClockFromNative",
+                                                                "(IJI)I");
 
 
     RegisterMethodsOrDie(env, kRadioManagerClassPathName, gMethods, NELEM(gMethods));
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 568473c..c8b1784 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -184,51 +184,43 @@
     jint _minorRemaining;
     EGLint *minor = (EGLint *) 0;
 
-    if (!major_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "major == null";
-        goto exit;
+    if (major_ref) {
+        if (majorOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "majorOffset < 0";
+            goto exit;
+        }
+        _majorRemaining = _env->GetArrayLength(major_ref) - majorOffset;
+        if (_majorRemaining < 1) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "length - majorOffset < 1 < needed";
+            goto exit;
+        }
+        major_base = (EGLint *)
+            _env->GetIntArrayElements(major_ref, (jboolean *)0);
+        major = major_base + majorOffset;
     }
-    if (majorOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "majorOffset < 0";
-        goto exit;
-    }
-    _majorRemaining = _env->GetArrayLength(major_ref) - majorOffset;
-    if (_majorRemaining < 1) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length - majorOffset < 1 < needed";
-        goto exit;
-    }
-    major_base = (EGLint *)
-        _env->GetIntArrayElements(major_ref, (jboolean *)0);
-    major = major_base + majorOffset;
 
-    if (!minor_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "minor == null";
-        goto exit;
+    if (minor_ref) {
+        if (minorOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "minorOffset < 0";
+            goto exit;
+        }
+        _minorRemaining = _env->GetArrayLength(minor_ref) - minorOffset;
+        if (_minorRemaining < 1) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "length - minorOffset < 1 < needed";
+            goto exit;
+        }
+        minor_base = (EGLint *)
+            _env->GetIntArrayElements(minor_ref, (jboolean *)0);
+        minor = minor_base + minorOffset;
     }
-    if (minorOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "minorOffset < 0";
-        goto exit;
-    }
-    _minorRemaining = _env->GetArrayLength(minor_ref) - minorOffset;
-    if (_minorRemaining < 1) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length - minorOffset < 1 < needed";
-        goto exit;
-    }
-    minor_base = (EGLint *)
-        _env->GetIntArrayElements(minor_ref, (jboolean *)0);
-    minor = minor_base + minorOffset;
 
     _returnValue = eglInitialize(
         (EGLDisplay)dpy_native,
@@ -289,26 +281,22 @@
     jint _num_configRemaining;
     EGLint *num_config = (EGLint *) 0;
 
-    if (!configs_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "configs == null";
-        goto exit;
+    if (configs_ref) {
+        if (configsOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "configsOffset < 0";
+            goto exit;
+        }
+        _configsRemaining = _env->GetArrayLength(configs_ref) - configsOffset;
+        if (_configsRemaining < config_size) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "length - configsOffset < config_size < needed";
+            goto exit;
+        }
+        configs = new EGLConfig[_configsRemaining];
     }
-    if (configsOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "configsOffset < 0";
-        goto exit;
-    }
-    _configsRemaining = _env->GetArrayLength(configs_ref) - configsOffset;
-    if (_configsRemaining < config_size) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length - configsOffset < config_size < needed";
-        goto exit;
-    }
-    configs = new EGLConfig[_configsRemaining];
 
     if (!num_config_ref) {
         _exception = 1;
@@ -401,26 +389,22 @@
         goto exit;
     }
 
-    if (!configs_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "configs == null";
-        goto exit;
+    if (configs_ref) {
+        if (configsOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "configsOffset < 0";
+            goto exit;
+        }
+        _configsRemaining = _env->GetArrayLength(configs_ref) - configsOffset;
+        if (_configsRemaining < config_size) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "length - configsOffset < config_size < needed";
+            goto exit;
+        }
+        configs = new EGLConfig[_configsRemaining];
     }
-    if (configsOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "configsOffset < 0";
-        goto exit;
-    }
-    _configsRemaining = _env->GetArrayLength(configs_ref) - configsOffset;
-    if (_configsRemaining < config_size) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length - configsOffset < config_size < needed";
-        goto exit;
-    }
-    configs = new EGLConfig[_configsRemaining];
 
     if (!num_config_ref) {
         _exception = 1;
@@ -546,18 +530,32 @@
     EGLint *attrib_list = (EGLint *) 0;
     android::sp<ANativeWindow> window;
 
-    if (!attrib_list_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "attrib_list == null";
-        goto exit;
+    if (attrib_list_ref) {
+        if (offset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "offset < 0";
+            goto exit;
+        }
+        _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+        attrib_list_base = (EGLint *)
+            _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
+        attrib_list = attrib_list_base + offset;
+        attrib_list_sentinel = 0;
+        for (int i = _remaining - 1; i >= 0; i--)  {
+            if (*((EGLint*)(attrib_list + i)) == EGL_NONE){
+                attrib_list_sentinel = 1;
+                break;
+            }
+        }
+        if (attrib_list_sentinel == 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "attrib_list must contain EGL_NONE!";
+            goto exit;
+        }
     }
-    if (offset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "offset < 0";
-        goto exit;
-    }
+
     if (win == NULL) {
 not_valid_surface:
         _exception = 1;
@@ -571,24 +569,6 @@
     if (window == NULL)
         goto not_valid_surface;
 
-    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
-    attrib_list_base = (EGLint *)
-        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
-    attrib_list = attrib_list_base + offset;
-    attrib_list_sentinel = 0;
-    for (int i = _remaining - 1; i >= 0; i--)  {
-        if (*((EGLint*)(attrib_list + i)) == EGL_NONE){
-            attrib_list_sentinel = 1;
-            break;
-        }
-    }
-    if (attrib_list_sentinel == 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "attrib_list must contain EGL_NONE!";
-        goto exit;
-    }
-
     _returnValue = eglCreateWindowSurface(
         (EGLDisplay)dpy_native,
         (EGLConfig)config_native,
@@ -703,34 +683,30 @@
     jint _remaining;
     EGLint *attrib_list = (EGLint *) 0;
 
-    if (!attrib_list_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "attrib_list == null";
-        goto exit;
-    }
-    if (offset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "offset < 0";
-        goto exit;
-    }
-    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
-    attrib_list_base = (EGLint *)
-        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
-    attrib_list = attrib_list_base + offset;
-    attrib_list_sentinel = false;
-    for (int i = _remaining - 1; i >= 0; i--)  {
-        if (attrib_list[i] == EGL_NONE){
-            attrib_list_sentinel = true;
-            break;
+    if (attrib_list_ref) {
+        if (offset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "offset < 0";
+            goto exit;
         }
-    }
-    if (attrib_list_sentinel == false) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "attrib_list must contain EGL_NONE!";
-        goto exit;
+        _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+        attrib_list_base = (EGLint *)
+            _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
+        attrib_list = attrib_list_base + offset;
+        attrib_list_sentinel = false;
+        for (int i = _remaining - 1; i >= 0; i--)  {
+            if (attrib_list[i] == EGL_NONE){
+                attrib_list_sentinel = true;
+                break;
+            }
+        }
+        if (attrib_list_sentinel == false) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "attrib_list must contain EGL_NONE!";
+            goto exit;
+        }
     }
 
     _returnValue = eglCreatePbufferSurface(
@@ -882,34 +858,30 @@
     jint _remaining;
     EGLint *attrib_list = (EGLint *) 0;
 
-    if (!attrib_list_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "attrib_list == null";
-        goto exit;
-    }
-    if (offset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "offset < 0";
-        goto exit;
-    }
-    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
-    attrib_list_base = (EGLint *)
-        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
-    attrib_list = attrib_list_base + offset;
-    attrib_list_sentinel = false;
-    for (int i = _remaining - 1; i >= 0; i--)  {
-        if (attrib_list[i] == EGL_NONE){
-            attrib_list_sentinel = true;
-            break;
+    if (attrib_list_ref) {
+        if (offset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "offset < 0";
+            goto exit;
         }
-    }
-    if (attrib_list_sentinel == false) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "attrib_list must contain EGL_NONE!";
-        goto exit;
+        _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+        attrib_list_base = (EGLint *)
+            _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
+        attrib_list = attrib_list_base + offset;
+        attrib_list_sentinel = false;
+        for (int i = _remaining - 1; i >= 0; i--)  {
+            if (attrib_list[i] == EGL_NONE){
+                attrib_list_sentinel = true;
+                break;
+            }
+        }
+        if (attrib_list_sentinel == false) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "attrib_list must contain EGL_NONE!";
+            goto exit;
+        }
     }
 
     _returnValue = eglCreatePbufferFromClientBuffer(
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index b9f61a9..ac3bf7a 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -1783,22 +1783,18 @@
     jint _nameRemaining;
     char *name = (char *) 0;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        length_base = (GLsizei *)
+            _env->GetIntArrayElements(length_ref, (jboolean *)0);
+        length = length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    length_base = (GLsizei *)
-        _env->GetIntArrayElements(length_ref, (jboolean *)0);
-    length = length_base + lengthOffset;
 
     if (!size_ref) {
         _exception = 1;
@@ -2111,22 +2107,18 @@
     jint _nameRemaining;
     char *name = (char *) 0;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        length_base = (GLsizei *)
+            _env->GetIntArrayElements(length_ref, (jboolean *)0);
+        length = length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    length_base = (GLsizei *)
-        _env->GetIntArrayElements(length_ref, (jboolean *)0);
-    length = length_base + lengthOffset;
 
     if (!size_ref) {
         _exception = 1;
@@ -2434,28 +2426,24 @@
     jint _shadersRemaining;
     GLuint *shaders = (GLuint *) 0;
 
-    if (!count_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "count == null";
-        goto exit;
+    if (count_ref) {
+        if (countOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "countOffset < 0";
+            goto exit;
+        }
+        _countRemaining = _env->GetArrayLength(count_ref) - countOffset;
+        if (_countRemaining < 1) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "length - countOffset < 1 < needed";
+            goto exit;
+        }
+        count_base = (GLsizei *)
+            _env->GetIntArrayElements(count_ref, (jboolean *)0);
+        count = count_base + countOffset;
     }
-    if (countOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "countOffset < 0";
-        goto exit;
-    }
-    _countRemaining = _env->GetArrayLength(count_ref) - countOffset;
-    if (_countRemaining < 1) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length - countOffset < 1 < needed";
-        goto exit;
-    }
-    count_base = (GLsizei *)
-        _env->GetIntArrayElements(count_ref, (jboolean *)0);
-    count = count_base + countOffset;
 
     if (!shaders_ref) {
         _exception = 1;
@@ -2526,20 +2514,18 @@
             goto exit;
         }
     }
-    if (shaders_buf) {
-        shaders = (GLuint *)getPointer(_env, shaders_buf, (jarray*)&_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
-        if (_shadersRemaining < maxcount) {
-            _exception = 1;
-            _exceptionType = "java/lang/IllegalArgumentException";
-            _exceptionMessage = "remaining() < maxcount < needed";
-            goto exit;
-        }
+    shaders = (GLuint *)getPointer(_env, shaders_buf, (jarray*)&_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
+    if (_shadersRemaining < maxcount) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "remaining() < maxcount < needed";
+        goto exit;
     }
     if (count_buf && count == NULL) {
         char * _countBase = (char *)_env->GetIntArrayElements(_countArray, (jboolean *) 0);
         count = (GLsizei *) (_countBase + _countBufferOffset);
     }
-    if (shaders_buf && shaders == NULL) {
+    if (shaders == NULL) {
         char * _shadersBase = (char *)_env->GetIntArrayElements(_shadersArray, (jboolean *) 0);
         shaders = (GLuint *) (_shadersBase + _shadersBufferOffset);
     }
@@ -3262,22 +3248,18 @@
     jint _sourceRemaining;
     char *source = (char *) 0;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        length_base = (GLsizei *)
+            _env->GetIntArrayElements(length_ref, (jboolean *)0);
+        length = length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    length_base = (GLsizei *)
-        _env->GetIntArrayElements(length_ref, (jboolean *)0);
-    length = length_base + lengthOffset;
 
     if (!source_ref) {
         _exception = 1;
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 8eb5044..c9b5af7 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -501,8 +501,10 @@
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
 
-    pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
-    if (pixels == NULL) {
+    if (pixels_buf) {
+        pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
+    }
+    if (pixels_buf && pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
     }
@@ -1910,22 +1912,18 @@
     jint _nameRemaining;
     char *name = (char *) 0;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        length_base = (GLsizei *)
+            _env->GetIntArrayElements(length_ref, (jboolean *)0);
+        length = length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    length_base = (GLsizei *)
-        _env->GetIntArrayElements(length_ref, (jboolean *)0);
-    length = length_base + lengthOffset;
 
     if (!size_ref) {
         _exception = 1;
@@ -3591,22 +3589,18 @@
     jint _nameRemaining;
     GLchar* _name = (GLchar*)0;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        _length_base = (GLsizei*)_env->GetIntArrayElements(
+                length_ref, (jboolean*)0);
+        _length = _length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    _length_base = (GLsizei*)_env->GetIntArrayElements(
-            length_ref, (jboolean*)0);
-    _length = _length_base + lengthOffset;
 
     if (!name_ref) {
         _exception = 1;
@@ -3900,22 +3894,18 @@
     jint _valuesRemaining;
     GLint *values = (GLint *) 0;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        length_base = (GLsizei *)
+            _env->GetIntArrayElements(length_ref, (jboolean *)0);
+        length = length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    length_base = (GLsizei *)
-        _env->GetIntArrayElements(length_ref, (jboolean *)0);
-    length = length_base + lengthOffset;
 
     if (!values_ref) {
         _exception = 1;
@@ -3969,9 +3959,11 @@
     jint _valuesRemaining;
     GLint *values = (GLint *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    if (length_buf) {
+        length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    }
     values = (GLint *)getPointer(_env, values_buf, (jarray*)&_valuesArray, &_valuesRemaining, &_valuesBufferOffset);
-    if (length == NULL) {
+    if (length_buf && length == NULL) {
         char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
@@ -4772,22 +4764,18 @@
     jint _binaryRemaining;
     GLvoid *binary = (GLvoid *) 0;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        length_base = (GLsizei *)
+            _env->GetIntArrayElements(length_ref, (jboolean *)0);
+        length = length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    length_base = (GLsizei *)
-        _env->GetIntArrayElements(length_ref, (jboolean *)0);
-    length = length_base + lengthOffset;
 
     if (!binaryFormat_ref) {
         _exception = 1;
@@ -4853,10 +4841,12 @@
     jint _binaryRemaining;
     GLvoid *binary = (GLvoid *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    if (length_buf) {
+        length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    }
     binaryFormat = (GLenum *)getPointer(_env, binaryFormat_buf, (jarray*)&_binaryFormatArray, &_binaryFormatRemaining, &_binaryFormatBufferOffset);
     binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
-    if (length == NULL) {
+    if (length_buf && length == NULL) {
         char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp
index e427388..5751add 100644
--- a/core/jni/android_opengl_GLES31.cpp
+++ b/core/jni/android_opengl_GLES31.cpp
@@ -714,22 +714,18 @@
         _env->GetIntArrayElements(props_ref, (jboolean *)0);
     props = props_base + propsOffset;
 
-    if (!length_ref) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "length == null";
-        goto exit;
+    if (length_ref) {
+        if (lengthOffset < 0) {
+            _exception = 1;
+            _exceptionType = "java/lang/IllegalArgumentException";
+            _exceptionMessage = "lengthOffset < 0";
+            goto exit;
+        }
+        _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
+        length_base = (GLsizei *)
+            _env->GetIntArrayElements(length_ref, (jboolean *)0);
+        length = length_base + lengthOffset;
     }
-    if (lengthOffset < 0) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "lengthOffset < 0";
-        goto exit;
-    }
-    _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    length_base = (GLsizei *)
-        _env->GetIntArrayElements(length_ref, (jboolean *)0);
-    length = length_base + lengthOffset;
 
     if (!params_ref) {
         _exception = 1;
@@ -795,13 +791,15 @@
     GLint *params = (GLint *) 0;
 
     props = (GLenum *)getPointer(_env, props_buf, (jarray*)&_propsArray, &_propsRemaining, &_propsBufferOffset);
-    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    if (length_buf) {
+        length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    }
     params = (GLint *)getPointer(_env, params_buf, (jarray*)&_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
     if (props == NULL) {
         char * _propsBase = (char *)_env->GetIntArrayElements(_propsArray, (jboolean *) 0);
         props = (GLenum *) (_propsBase + _propsBufferOffset);
     }
-    if (length == NULL) {
+    if (length_buf && length == NULL) {
         char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp
index 180c693..5be7be0 100644
--- a/core/jni/android_opengl_GLES31Ext.cpp
+++ b/core/jni/android_opengl_GLES31Ext.cpp
@@ -646,13 +646,9 @@
     const char * _exceptionMessage = NULL;
     const char* _nativelabel = 0;
 
-    if (!label) {
-        _exception = 1;
-        _exceptionType = "java/lang/IllegalArgumentException";
-        _exceptionMessage = "label == null";
-        goto exit;
+    if (label) {
+        _nativelabel = _env->GetStringUTFChars(label, 0);
     }
-    _nativelabel = _env->GetStringUTFChars(label, 0);
 
     glObjectLabelKHR(
         (GLenum)identifier,
@@ -660,8 +656,6 @@
         (GLsizei)length,
         (GLchar *)_nativelabel
     );
-
-exit:
     if (_nativelabel) {
         _env->ReleaseStringUTFChars(label, _nativelabel);
     }
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 55b7e7e..90606a35 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -578,22 +578,6 @@
     return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
 }
 
-static void android_content_AssetManager_setLocale(JNIEnv* env, jobject clazz,
-                                                jstring locale)
-{
-    ScopedUtfChars locale8(env, locale);
-    if (locale8.c_str() == NULL) {
-        return;
-    }
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return;
-    }
-
-    am->setLocale(locale8.c_str());
-}
-
 static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
 {
     Vector<String8> locales;
@@ -2168,8 +2152,6 @@
         (void*) android_content_AssetManager_isUpToDate },
 
     // Resources.
-    { "setLocale",      "(Ljava/lang/String;)V",
-        (void*) android_content_AssetManager_setLocale },
     { "getLocales",      "()[Ljava/lang/String;",
         (void*) android_content_AssetManager_getLocales },
     { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
diff --git a/core/jni/android_util_PathParser.cpp b/core/jni/android_util_PathParser.cpp
new file mode 100644
index 0000000..245aa0f
--- /dev/null
+++ b/core/jni/android_util_PathParser.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni.h"
+
+#include <PathParser.h>
+#include <SkPath.h>
+
+#include <android/log.h>
+#include "core_jni_helpers.h"
+
+namespace android {
+
+static bool parseStringForPath(JNIEnv* env, jobject, jlong skPathHandle, jstring inputPathStr,
+        jint strLength) {
+    const char* pathString = env->GetStringUTFChars(inputPathStr, NULL);
+    SkPath* skPath = reinterpret_cast<SkPath*>(skPathHandle);
+
+    android::uirenderer::PathParser::ParseResult result;
+    android::uirenderer::PathParser::parseStringForSkPath(skPath, &result, pathString, strLength);
+    env->ReleaseStringUTFChars(inputPathStr, pathString);
+    if (result.failureOccurred) {
+        ALOGE(result.failureMessage.c_str());
+    }
+    return !result.failureOccurred;
+}
+
+static const JNINativeMethod gMethods[] = {
+    {"nParseStringForPath", "(JLjava/lang/String;I)Z", (void*)parseStringForPath}
+};
+
+int register_android_util_PathParser(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "android/util/PathParser", gMethods, NELEM(gMethods));
+}
+};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 561bcbc..6bdf71b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1683,6 +1683,10 @@
     <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"
         android:protectionLevel="system|signature" />
 
+    <!-- @hide -->
+    <permission android:name="android.permission.STORAGE_INTERNAL"
+        android:protectionLevel="signature" />
+
     <!-- Allows access to ASEC non-destructive API calls
          @hide  -->
     <permission android:name="android.permission.ASEC_ACCESS"
@@ -2702,7 +2706,9 @@
                  android:killAfterRestore="false"
                  android:icon="@drawable/ic_launcher_android"
                  android:supportsRtl="true"
-                 android:theme="@style/Theme.Material.DayNight.DarkActionBar">
+                 android:theme="@style/Theme.Material.DayNight.DarkActionBar"
+                 android:forceDeviceEncrypted="true"
+                 android:encryptionAware="true">
         <activity android:name="com.android.internal.app.ChooserActivity"
                 android:theme="@style/Theme.DeviceDefault.Resolver"
                 android:finishOnCloseSystemDialogs="true"
diff --git a/core/res/res/layout/date_picker_header_material.xml b/core/res/res/layout/date_picker_header_material.xml
index a4388f6..821b588 100644
--- a/core/res/res/layout/date_picker_header_material.xml
+++ b/core/res/res/layout/date_picker_header_material.xml
@@ -19,19 +19,27 @@
               android:id="@+id/date_picker_header"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
-              android:paddingBottom="18dp"
               android:paddingStart="?attr/dialogPreferredPadding"
               android:paddingEnd="?attr/dialogPreferredPadding"
-              android:orientation="vertical">
+              android:paddingTop="16dp"
+              android:paddingBottom="18dp"
+              android:orientation="vertical"
+              android:clipToPadding="false"
+              android:clipChildren="false">
 
-    <!-- Top padding should stay on this view so that
-         the touch target is a bit larger. -->
     <TextView
         android:id="@+id/date_picker_header_year"
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:paddingTop="16dp"
-        android:textAppearance="@style/TextAppearance.Material.DatePicker.YearLabel" />
+        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"
diff --git a/core/res/res/layout/date_picker_month_item_material.xml b/core/res/res/layout/date_picker_month_item_material.xml
index cb79cee..52f7b8e 100644
--- a/core/res/res/layout/date_picker_month_item_material.xml
+++ b/core/res/res/layout/date_picker_month_item_material.xml
@@ -21,4 +21,5 @@
     android:layout_height="wrap_content"
     android:paddingStart="@dimen/day_picker_padding_horizontal"
     android:paddingEnd="@dimen/day_picker_padding_horizontal"
-    android:paddingTop="@dimen/day_picker_padding_top" />
+    android:paddingTop="@dimen/day_picker_padding_top"
+    android:focusable="true"/>
diff --git a/core/res/res/layout/day_picker_content_material.xml b/core/res/res/layout/day_picker_content_material.xml
index b582d74..d77e8dc 100644
--- a/core/res/res/layout/day_picker_content_material.xml
+++ b/core/res/res/layout/day_picker_content_material.xml
@@ -33,7 +33,9 @@
         android:src="@drawable/ic_chevron_start"
         android:background="?attr/selectableItemBackgroundBorderless"
         android:contentDescription="@string/date_picker_prev_month_button"
-        android:visibility="invisible" />
+        android:visibility="invisible"
+        android:nextFocusForward="@+id/next"
+        android:nextFocusDown="@+id/month_view" />
 
     <ImageButton
         android:id="@+id/next"
@@ -44,6 +46,8 @@
         android:src="@drawable/ic_chevron_end"
         android:background="?attr/selectableItemBackgroundBorderless"
         android:contentDescription="@string/date_picker_next_month_button"
-        android:visibility="invisible" />
+        android:visibility="invisible"
+        android:nextFocusForward="@+id/month_view"
+        android:nextFocusDown="@+id/month_view"/>
 
 </FrameLayout>
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index f073c33..fc53a1a 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -24,18 +24,23 @@
     android:background="@android:color/transparent"
     android:layout_removeBorders="true">
 
-    <ListView android:id="@android:id/list"
-        style="?attr/preferenceFragmentListStyle"
+    <FrameLayout
+        android:id="@android:id/list_container"
         android:layout_width="match_parent"
         android:layout_height="0px"
-        android:layout_weight="1"
-        android:paddingTop="0dip"
-        android:paddingBottom="@dimen/preference_fragment_padding_bottom"
-        android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
-        android:clipToPadding="false"
-        android:drawSelectorOnTop="false"
-        android:cacheColorHint="@android:color/transparent"
-        android:scrollbarAlwaysDrawVerticalTrack="true" />
+        android:layout_weight="1">
+        <ListView android:id="@android:id/list"
+            style="?attr/preferenceFragmentListStyle"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:paddingTop="0dip"
+            android:paddingBottom="@dimen/preference_fragment_padding_bottom"
+            android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
+            android:clipToPadding="false"
+            android:drawSelectorOnTop="false"
+            android:cacheColorHint="@android:color/transparent"
+            android:scrollbarAlwaysDrawVerticalTrack="true" />
+    </FrameLayout>
 
     <TextView android:id="@android:id/empty"
         android:layout_width="match_parent"
diff --git a/core/res/res/layout/preference_list_fragment_material.xml b/core/res/res/layout/preference_list_fragment_material.xml
index 62bdffd..e411c0e 100644
--- a/core/res/res/layout/preference_list_fragment_material.xml
+++ b/core/res/res/layout/preference_list_fragment_material.xml
@@ -24,18 +24,23 @@
     android:background="@android:color/transparent"
     android:layout_removeBorders="true">
 
-    <ListView android:id="@android:id/list"
-        style="?attr/preferenceFragmentListStyle"
+    <FrameLayout
+        android:id="@android:id/list_container"
         android:layout_width="match_parent"
         android:layout_height="0px"
-        android:layout_weight="1"
-        android:paddingTop="0dip"
-        android:paddingBottom="@dimen/preference_fragment_padding_bottom"
-        android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
-        android:clipToPadding="false"
-        android:drawSelectorOnTop="false"
-        android:cacheColorHint="@android:color/transparent"
-        android:scrollbarAlwaysDrawVerticalTrack="true" />
+        android:layout_weight="1">
+        <ListView android:id="@android:id/list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:paddingTop="0dip"
+            android:paddingBottom="@dimen/preference_fragment_padding_bottom"
+            style="?attr/preferenceFragmentListStyle"
+            android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
+            android:clipToPadding="false"
+            android:drawSelectorOnTop="false"
+            android:cacheColorHint="@android:color/transparent"
+            android:scrollbarAlwaysDrawVerticalTrack="true" />
+    </FrameLayout>
 
     <TextView android:id="@android:id/empty"
         android:layout_width="match_parent"
diff --git a/core/res/res/layout/preference_widget_switch.xml b/core/res/res/layout/preference_widget_switch.xml
index 25e8aa6..80c572b 100644
--- a/core/res/res/layout/preference_widget_switch.xml
+++ b/core/res/res/layout/preference_widget_switch.xml
@@ -17,7 +17,7 @@
 <!-- Layout used by SwitchPreference for the switch widget style. This is inflated
      inside android.R.layout.preference. -->
 <Switch xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+android:id/switchWidget"
+    android:id="@+android:id/switch_widget"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:focusable="false"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index f5de462..f8b88a7 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Sien die handleiding of kontak kliëntediens."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart is gesluit."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ontsluit tans SIM-kaart…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingevoer. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingevoer. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. Na <xliff:g id="NUMBER_1">%d</xliff:g> nóg onsuksesvolle pogings sal jy gevra word om jou tablet te ontsluit met gebruik van jou Google-aanmelddetails.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd getrek. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou TV met jou Google-aanmelding te ontsluit.\n\n Probeer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes weer."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou foon te ontsluit met gebruik van jou Google-aanmelddetails.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer probeer om die tablet verkeerde te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle poging, sal die tablet terug gestel word nia die fabrieksverstek en alle gebruikerdata sal verlore wees."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Jy het die TV <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd probeer ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings sal die TV na die verstekfabriekinstellings teruggestel word en sal alle gebruikerdata verloor word."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer probeer om die foon verkeerde te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle poging sal die foon terug gestel word na die fabrieksverstek en alle gebruikerdata sal verlore wees."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd ingevoer. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd ingevoer. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na <xliff:g id="NUMBER_1">%2$d</xliff:g> nóg onsuksesvolle pogings sal jy gevra word om jou tablet te ontsluit met gebruik van jou Google-aanmelddetails.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd getrek. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou TV met jou Google-aanmelding te ontsluit.\n\n Probeer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes weer."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou foon te ontsluit met gebruik van jou Google-aanmelddetails.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Jy het <xliff:g id="NUMBER_0">%1$d</xliff:g> keer probeer om die tablet verkeerde te ontsluit. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle poging, sal die tablet terug gestel word nia die fabrieksverstek en alle gebruikerdata sal verlore wees."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Jy het die TV <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal die TV na die verstekfabriekinstellings teruggestel word en sal alle gebruikerdata verloor word."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Jy het <xliff:g id="NUMBER_0">%1$d</xliff:g> keer probeer om die foon verkeerde te ontsluit. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle poging sal die foon terug gestel word na die fabrieksverstek en alle gebruikerdata sal verlore wees."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Jy het die tablet <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die tablet sal nou terug gestel word na die fabrieksverstek."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Jy het die TV <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die TV sal nou na die verstekfabriekinstellings teruggestel word."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Jy <xliff:g id="NUMBER">%d</xliff:g> keer probeer om die foon verkeerd te ontsluit. Die foon sal nou terug gestel word na die fabrieksvertek."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"woord"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"skakel"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"reël"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabriektoets het gefaal"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Die FACTORY_TEST-handeling word net ondersteun vir pakkette wat in /system/app geïnstalleer is."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Geen pakket is gevind wat die FACTORY_TEST-handeling bied nie."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikernaam of wagwoord."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Het jy jou gebruikernaam of wagwoord vergeet?\nBesoek "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontroleer tans rekening..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jy het jou PIN <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingetik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer jou wagwoord verkeerdelik getik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die tablet na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Jy het die TV <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd probeer ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings sal die TV na die verstekfabriekinstellings teruggestel word en sal alle gebruikerdata verloor word."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die foon na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jy het jou PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd ingetik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jy het <xliff:g id="NUMBER_0">%1$d</xliff:g> keer jou wagwoord verkeerdelik getik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerdelik geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jy het <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings, sal die tablet na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Jy het die TV <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd probeer ontsluit. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal die TV na die verstekfabriekinstellings teruggestel word en sal alle gebruikerdata verloor word."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jy het <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings, sal die foon na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Die tablet sal nou na fabrieksverstek teruggestel word."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Jy het die TV <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die TV sal nou na die verstekfabriekinstellings teruggestel word."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Die foon sal nou na fabrieksverstek teruggestel word."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd getrek. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou TV met \'n e-posrekening te ontsluit.\n\n Probeer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes weer."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd getrek. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou TV met \'n e-posrekening te ontsluit.\n\n Probeer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes weer."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwyder"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Verhoog volume bo aanbevole vlak?\n\nOm lang tydperke teen hoë volume te luister, kan jou gehoor beskadig."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8f0818c..d9246bc 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g>ጊዜ በስህተት ስለውታል።\n\nእባክህ እንደገና ከ<xliff:g id="NUMBER_1">%d</xliff:g>ሰከንዶች በኋላ ሞክር።"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g>ጊዚያቶች የይለፍ ቃልህን በስህተት ተይበኻል፡፡በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ \n\nእንደገና ሞክር፡፡"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g>ጊዚያቶች ፒንህን በስህተት ተይበኻል፡፡በ\nሰኮንዶች ውስጥ \n<xliff:g id="NUMBER_1">%d</xliff:g>እንደገና ሞክር፡፡"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g>ጊዜ በስህተት ስለውታል።ከ<xliff:g id="NUMBER_1">%d</xliff:g>የበለጠ ያልተሳካ ሙከራ በኋላ፣ የGoogle መግቢያዎን ተጠቅመው ስልኩን እንዲከከፍቱ ይጠየቃሉ።\n\nእባክዎ እንደገና <xliff:g id="NUMBER_2">%d</xliff:g>ከሰከንዶች በኋላ ይሞክሩ።"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"የእርስዎን ስርዓተ ጥለት <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የGoogle መግቢያዎን ተጠቅመው የእርስዎን ቴሌቪዥን እንዲያስከፍቱ ይጠየቃሉ።\n\n በ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ።"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"የመክፈቻ ስርዓተ ጥለቱን<xliff:g id="NUMBER_0">%d</xliff:g>ጊዜ በስህተት ስለውታል።ከ<xliff:g id="NUMBER_1">%d</xliff:g> የበለጠ ያልተሳካ ሙከራ በኋላ፣ የGoogle መግቢያዎን ተጠቅመው ስልኩን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ እንደገና ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ ይሞክሩ።"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ይህን tablet <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ያህል በስህተት ለማስከፈት ሞክረሃል፡፡ ከ <xliff:g id="NUMBER_1">%d</xliff:g> በላይ ያልተሳኩ ሙከራዎች በኋላ፣ ይህ tablet አሁን በፋብሪካ ነባሪ ቅንጅት ዳግም ይቀናበርና ሁሉም የተጠቃሚው ውሂብ ይጠፋል፡፡"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ቴሌቪዥኑን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ባልተሳካ ሁኔታ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ቴሌቪዥኑ ወደ የፋብሪካ ነባሪ ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ይህን ስልክ <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ያህል በስህተት ለማስከፈት ሞክረሃል፡፡ ከ <xliff:g id="NUMBER_1">%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>ጊዚያቶች የይለፍ ቃልህን በስህተት ተይበኻል፡፡በ<xliff:g id="NUMBER_1">%2$d</xliff:g> ሰኮንዶች ውስጥ \n\nእንደገና ሞክር፡፡"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<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_at_wipe" product="tablet" msgid="6128106399745755604">"ይህን tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ያህል በስህተት ለማስከፈት ሞክረሃል፡፡ ከ <xliff:g id="NUMBER_1">%2$d</xliff:g> በላይ ያልተሳኩ ሙከራዎች በኋላ፣ ይህ tablet አሁን በፋብሪካ ነባሪ ቅንጅት ዳግም ይቀናበርና ሁሉም የተጠቃሚው ውሂብ ይጠፋል፡፡"</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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ይህን tablet <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ያህል በስህተት ለማስከፈት ሞክረሃል፡፡ ይህ tablet አሁን በፋብሪካ ነባሪ ቅንጅት ዳግም ይቀናበራል፡፡"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ቃል"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"አገናኝ"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"መስመር"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"የፋብሪካሙከራ ተስኗል"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"የፋብሪካ_ ሙከራ ርምጃበ/system/app አካታች ውስጥ የተጫነ ብቻ ተደግፏል።"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"የፋብሪካ_ሙከራ ርምጃ የሚያቀርብምንም አካታች አልተገኘም።"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ልክ ያልሆነ የተጠቃሚ ስም ወይም የይለፍ ቃል።"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"የተጠቃሚ ስምዎን ወይም የይለፍ ቃልዎን ረሱት?\n"<b>"google.com/accounts/recovery"</b>"ይጎብኙ።"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"መለያውን በማረጋገጥ ላይ…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ፒንዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልተየቡም። \n\nበ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"የይለፍ ቃልዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ተይበዋል።\n\nበ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"የመክፈቻ ስርዓተ ጥለትዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። \n\n ከ<xliff:g id="NUMBER_1">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ጡባዊ ቱኮውን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ጡባዊ ቱኮው በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ቴሌቪዥኑን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ባልተሳካ ሁኔታ ለማስከፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ቴሌቪዥኑ ወደ የፋብሪካ ነባሪ ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ስልኩን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ስልኩ በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ፒንዎን <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_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">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።\n\n ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ስርዓተ ጥለትዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው የእርስዎን ቴሌቪዥን እንዲያስከፍቱ ይጠየቃሉ።\n\n በ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ።"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ ከ<xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 49997cd..c62fb2c 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -686,15 +686,15 @@
     <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">%d</xliff:g> مرة.\n\nالرجاء إعادة المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"لقد كتبت كلمة المرور <xliff:g id="NUMBER_0">%d</xliff:g> مرة بشكل غير صحيح. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"‏لقد كتبت رمز PIN <xliff:g id="NUMBER_0">%d</xliff:g> مرة بشكل غير صحيح. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"‏لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"‏لديك <xliff:g id="NUMBER_0">%d</xliff:g> من محاولات رسم نقش إلغاء القفل غير الصحيحة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، سيُطلب منك إلغاء قفل التلفزيون من خلال تسجيل الدخول إلى Google.\n\n يمكنك إعادة التجربة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"‏لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"لقد حاولت إلغاء تأمين الجهاز اللوحي <xliff:g id="NUMBER_0">%d</xliff:g> من المرات. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة، ستتم إعادة تعيين الجهاز اللوحي إلى الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"لديك <xliff:g id="NUMBER_0">%d</xliff:g> من محاولات إلغاء قفل التلفزيون غير الصحيحة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة ضبط التلفزيون على إعدادات المصنع الافتراضية وستفقد جميع بيانات المستخدم."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"لقد حاولت إلغاء تأمين الهاتف <xliff:g id="NUMBER_0">%d</xliff:g> من المرات. بعد <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"لقد حاولت إلغاء تأمين الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الجهاز اللوحي إلى الإعدادات الافتراضية للمصنع."</string>
     <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>
@@ -746,8 +746,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"كلمة"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"رابط"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"سطر"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"أخفق اختبار المصنع"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"‏إجراء FACTORY_TEST غير متاح سوى للحزم المثبتة في /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"‏لم يتم العثور على أية حزمة توفر إجراء FACTORY_TEST."</string>
@@ -1317,18 +1315,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"اسم مستخدم غير صحيح أو كلمة مرور غير صالحة."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"‏هل نسيت اسم المستخدم أو كلمة المرور؟\nانتقل إلى "<b>"google.com/accounts/recovery"</b>"."</string>
     <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">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"لقد رسمت نقش إلغاء التأمين بطريقة غير صحيحة <xliff:g id="NUMBER_0">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"لقد حاولت إلغاء تأمين الجهاز اللوحي بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الجهاز اللوحي على الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"لديك <xliff:g id="NUMBER_0">%d</xliff:g> من محاولات إلغاء قفل التلفزيون غير الصحيحة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة ضبط التلفزيون على إعدادات المصنع الافتراضية وستفقد جميع بيانات المستخدم."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"لقد حاولت إلغاء تأمين الهاتف بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الهاتف على الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</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_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">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"لقد رسمت نقش إلغاء القفل بشكل غير صحيح عدد <xliff:g id="NUMBER_0">%d</xliff:g> من المرات. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة، سيُطلب منك إلغاء قفل التلفزيون باستخدام حساب بريد إلكتروني.\n\n يمكنك إعادة التجربة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index aac3cb3..db91232 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"İstifadəçi Təlimatlarına baxın və ya Müştəri Xidmətlərinə müraciət edin."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kart kilidlənib."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SİM kartın kilidi açılır..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Siz kilid modelini <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə içində yenidən sınayın."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Siz PIN nömrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n \n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə içində təkrar sınayın."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız istəniləcək.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Siz kilidaçma nümunənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv daxil etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra sizdən Google girişindən istifadə etməklə TV-nizin kilidini açmağınız istəniləcəkdir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyəyə yenidən cəhd edin."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Siz TV <xliff:g id="NUMBER_0">%d</xliff:g> dəfə TV-nizin kilidini açmaq üçün səhv cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra TV standart parametrlərə qbərpa olunacaq və bütün istifadəçi məlumatları itəcəkdir."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon zavod ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Siz kilid modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkdiniz. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə içində yenidən sınayın."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrənizi <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Siz PIN nömrənizi <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etdiniz. \n \n <xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə içində təkrar sınayın."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız istəniləcək.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Siz kilidaçma nümunənizi <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə səhv daxil etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra sizdən Google girişindən istifadə etməklə TV-nizin kilidini açmağınız istəniləcəkdir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyəyə yenidən cəhd edin."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Siz TV <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə TV-nizin kilidini açmaq üçün səhv cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra TV standart parametrlərə qbərpa olunacaq və bütün istifadəçi məlumatları itəcəkdir."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon zavod ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Siz planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Planşet artıq defolt zavod halına sıfırlanacaq."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə TV-nizin kilidini açmaq üçün səhv cəhdlər etdiniz. TV indi standart parametrlərə bərpa olunacaqdır."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə səhv cəhd etdiniz. Telefonunuz indi zavod nizamlarına yenilənəcək."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"söz"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"xətt"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Zavod testi alınmadı"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Bu FACTORY_TEST fəaliyyəti yalnızca/sistemdə/tətbiqdə quraşdırılmış paketlər üçün dəstəklənir."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST əməliyyatını təsdiqləyən heç bir paket tapılmadı."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Yanlış istifadəçi adı və ya parol."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesab yoxlanılır..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Modelinizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkmisiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Siz <xliff:g id="NUMBER_0">%d</xliff:g> dəfə TV-nizin kilidini açmaq üçün səhv cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra TV standart parametrlərə bərpa olunacaq və bütün istifadəçi məlumatları itəcəkdir."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrənizi <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etdiniz. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə ərzində yenidən yoxlayın."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Modelinizi <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz.\n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Siz <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə TV-nizin kilidini açmaq üçün səhv cəhdlər etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra TV standart parametrlərə bərpa olunacaq və bütün istifadəçi məlumatları itəcəkdir."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. Planşet fabrik ayarlarına sıfırlanacaq."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Siz <xliff:g id="NUMBER">%d</xliff:g> dəfə TV-nizin kilidini açmaq üçün səhv cəhdlər etdiniz. TV indi standart parametrlərə bərpa olunacaqdır."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Siz kilidaçma nümunənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv daxil etdiniz. Daha <xliff:g id="NUMBER_1">%d</xliff:g> uğursuz cəhddən sonra sizdən e-poçt hesabından istifadə etməklə TV-nizin kilidini açmaq soruşulacaqdır.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyəyə yenidən cəhd edin."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz artıq modeli <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Siz kilidaçma nümunənizi <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə səhv daxil etdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra sizdən e-poçt hesabından istifadə etməklə TV-nizin kilidini açmaq soruşulacaqdır.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyəyə yenidən cəhd edin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz artıq modeli <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Yığışdır"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Səsin həcmi tövsiyə olunan səviyyədən artıq olsun?\n\nYüksək səsi uzun zaman dinləmək eşitmə qabiliyyətinizə zərər vura bilər."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b4da9cd..fcab6d0 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством данните си за вход в Google.\n\nОпитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Неправилно начертахте фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телевизора си посредством данните си за вход в Google.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством данните си за вход в Google.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Направихте опит да отключите таблета неправилно <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Опитахте да отключите телевизора <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени фабричните му настройки и всички потребителски данни ще бъдат заличени."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Направихте опит да отключите телефона неправилно <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%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">"Въведохте неправилно ПИН кода си <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Направихте опит да отключите таблета неправилно <xliff:g id="NUMBER">%d</xliff:g> пъти. Сега ще бъдат възстановени стандартните му фабрични настройки."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"дума"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"връзка"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ред"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Фабричният тест не бе успешен"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Действието FACTORY_TEST се поддържа само за пакети, инсталирани в /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Не бе намерен пакет, предоставящ действието FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Невалидно потребителско име или парола."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Забравили сте потребителското име или паролата си?\nПосетете "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Профилът се проверява…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Направихте опит да отключите неправилно таблета <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Опитахте да отключите телевизора <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени фабричните му настройки и всички потребителски данни ще бъдат заличени."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Направихте опит да отключите неправилно телефона <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Въведохте неправилно ПИН кода си <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_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">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Неправилно начертахте фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телевизора си посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index d439db9..d66c249 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ব্যবহারকারীর নির্দেশিকা দেখুন বা গ্রাহক পরিষেবা কেন্দ্রে যোগাযোগ করুন৷"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"সিম কার্ড লক করা আছে৷"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"সিম কার্ড আনলক করা হচ্ছে…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"আপনি আপনার আনলকের প্যাটার্ন আঁকার ক্ষেত্রে <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google সাইন ইন দিয়ে আপনার ট্যাবলেট আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google সাইন ইন দিয়ে আপনার টিভি আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে Google সাইন ইন দিয়ে আপনার ফোন আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন৷ আরো <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল চেষ্টার পরে, ট্যাবলেটটি ফ্যাক্টরী ডিফল্টে রিসেট হবে এবং ব্যবহারকারীর সমস্ত ডেটা মুছে যাবে৷"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে টিভি আনলক করার চেষ্টা করেছেন৷ <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনার টিভি ফ্যাক্টরি ডিফল্টে পুনঃসেট হবে এবং সমস্ত ব্যবহারকারীর ডেটা মুছে যাবে৷"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে ফোনটি আনলক করার চেষ্টা করেছেন৷ আরো <xliff:g id="NUMBER_1">%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">"আপনি আপনার পাসওয়ার্ড <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুল করে ট্যাবলেটটি আনলক করার চেষ্টা করেছেন৷ ট্যাবলেটটি এখন ফ্যাক্টরী ডিফল্টে রিসেট হবে৷"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"শব্দ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"লিঙ্ক"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"লাইন"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ফ্যাক্টরী পরীক্ষা ব্যর্থ হয়েছে"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ক্রিয়াটি শুধুমাত্র /system/app এ ইনস্টল থাকা প্যাকেজগুলি সমর্থন করে৷"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"এমন কোনো প্যাকেজ খুঁজে পাওয়া যায়নি যা FACTORY_TEST ক্রিয়া প্রদান করে৷"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"অবৈধ ব্যবহারকারী নাম অথবা পাসওয়ার্ড৷"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"আপনার ব্যবহারকারী নাম অথবা পাসওয়ার্ড ভুলে গেছেন?\n"<b>"google.com/accounts/recovery"</b>" এ যান৷"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"অ্যাকাউন্ট পরীক্ষা করা হচ্ছে..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"আপনি আপনার পাসওয়ার্ড <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল টাইপ করেছেন৷ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"আপনি আপনার আনলকের প্যাটার্ন আঁকার ক্ষেত্রে <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করেছেন৷ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"আপনি আপনার ট্যাবলেট আনলকের প্রচেষ্টায় <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করেছেন৷ আর <xliff:g id="NUMBER_1">%d</xliff:g> বার অসফল প্রচেষ্টা করা হলে, ট্যাবলেটের সেটিংস ফ্যাক্টরি ডিফল্ট অনুযায়ী হয়ে যাবে এবং সমস্ত ব্যবহারকারী ডেটা হারিয়ে যাবে৷"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে টিভি আনলক করার চেষ্টা করেছেন৷ <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনার টিভি ফ্যাক্টরি ডিফল্টে পুনঃসেট হবে এবং সমস্ত ব্যবহারকারীর ডেটা মুছে যাবে৷"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"আপনি আপনার ফোন আনলকের প্রচেষ্টায় <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করেছেন৷ আর <xliff:g id="NUMBER_1">%d</xliff:g> বার অসফল প্রচেষ্টা করা হলে, ফোনটির সেটিংস ফ্যাক্টরি ডিফল্ট অনুযায়ী হয়ে যাবে এবং সমস্ত ব্যবহারকারী ডেটা হারিয়ে যাবে৷"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"আপনি আপনার পাসওয়ার্ড <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_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">%d</xliff:g> বার ভুল করেছেন৷ আর <xliff:g id="NUMBER_1">%d</xliff:g> বার অসফল প্রচেষ্টা করা হলে আপনাকে একটি ইমেল অ্যাকাউন্ট মারফত আপনার ট্যাবলেট আনলক করতে বলা হবে৷\n\n <xliff:g id="NUMBER_2">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে আপনার আনলক প্যাটার্ন অঙ্কিত করেছেন৷ আপনি <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনাকে কোনো ইমেল অ্যাকাউন্ট দিয়ে আপনার টিভি আনলক করার কথা বলা হবে৷\n\n <xliff:g id="NUMBER_2">%d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন৷"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"আপনি আপনার আনলকের প্যাটার্ন আঁকার ক্ষেত্রে <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করেছেন৷ আর <xliff:g id="NUMBER_1">%d</xliff:g> বার অসফল প্রচেষ্টা করা হলে আপনাকে একটি ইমেল অ্যাকাউন্ট মারফত আপনার ফোন আনলক করতে বলা হবে৷\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3a3c7e75..fae3b41 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guia de l\'usuari o posa\'t en contacte amb el servei d\'atenció al client."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La targeta SIM està bloquejada."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"S\'està desbloquejant la targeta SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Has dibuixat el patró de desbloqueig incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%d</xliff:g> intents més abans no hagis de desbloquejar el televisor amb les dades d\'inici de sessió de Google.\n\n Torna a provar-ho d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%d</xliff:g> intents més abans no es restableixin els valors de fàbrica de l\'aparell i es perdin totes les dades d\'usuari."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Has dibuixat el patró de desbloqueig incorrectament <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%2$d</xliff:g> intents més abans no hagis de desbloquejar el televisor amb les dades d\'inici de sessió de Google.\n\n Torna a provar-ho d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%2$d</xliff:g> intents més abans no es restableixin els valors de fàbrica de l\'aparell i es perdin totes les dades d\'usuari."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades incorrectament. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. Ara es restabliran els valors de fàbrica de l\'aparell."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades incorrectament. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"paraula"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"enllaç"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"línia"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Error a la prova de fàbrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"L\'acció FACTORY_TEST només és compatible amb els paquets instal·lats a /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No s\'ha trobat cap paquet que proporcioni l\'acció FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'usuari o contrasenya no vàlids."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Has oblidat el teu nom d\'usuari o la contrasenya?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"S\'està comprovant el compte…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%d</xliff:g> intents més abans no es restableixin els valors de fàbrica de l\'aparell i es perdin totes les dades d\'usuari."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, el telèfon es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%2$d</xliff:g> intents més abans no es restableixin els valors de fàbrica de l\'aparell i es perdin totes les dades d\'usuari."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, el telèfon es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. Ara es restabliran els valors de fàbrica de l\'aparell."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Has dibuixat el patró de desbloqueig incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%d</xliff:g> intents més abans no hagis de desbloquejar el televisor amb un compte de correu electrònic.\n\n Torna a provar-ho d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Has dibuixat el patró de desbloqueig incorrectament <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%2$d</xliff:g> intents més abans no hagis de desbloquejar el televisor amb un compte de correu electrònic.\n\n Torna a provar-ho d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Elimina"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Vols apujar el volum per sobre del nivell recomanat?\n\nSi escoltes música a un volum alt durant períodes llargs, pots danyar-te l\'oïda."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 188f186..b68d1ef 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -684,15 +684,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Další informace naleznete v uživatelské příručce; nebo kontaktujte zákaznickou podporu."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karta je zablokována."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odblokování SIM karty..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste použili nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení tabletu pomocí přihlášení Google.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"<xliff:g id="NUMBER_0">%d</xliff:g>× jste nesprávně načrtli bezpečnostní gesto. Po dalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspěšných pokusech budete požádáni o odemčení televize pomocí přihlášení přes Google.\n\nOpakujte akci za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení telefonu pomocí přihlášení Google.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"<xliff:g id="NUMBER_0">%d</xliff:g>× jste se neúspěšně pokusili odemknout televizi. Po dalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspěšných pokusech bude v televizi obnoveno tovární nastavení a veškerá uživatelská data budou ztracena."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste použili nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%2$d</xliff:g>) budete požádáni o odemčení tabletu pomocí přihlášení Google.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"<xliff:g id="NUMBER_0">%1$d</xliff:g>× jste nesprávně načrtli bezpečnostní gesto. Po dalších <xliff:g id="NUMBER_1">%2$d</xliff:g> neúspěšných pokusech budete požádáni o odemčení televize pomocí přihlášení přes Google.\n\nOpakujte akci za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%2$d</xliff:g>) budete požádáni o odemčení telefonu pomocí přihlášení Google.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%1$d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"<xliff:g id="NUMBER_0">%1$d</xliff:g>× jste se neúspěšně pokusili odemknout televizi. Po dalších <xliff:g id="NUMBER_1">%2$d</xliff:g> neúspěšných pokusech bude v televizi obnoveno tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%1$d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER">%d</xliff:g>krát. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"<xliff:g id="NUMBER">%d</xliff:g>× jste se neúspěšně pokusili odemknout televizi. V televizi nyní bude obnoveno tovární nastavení."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Telefon jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER">%d</xliff:g>krát. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"slovo"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"odkaz"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"řádek"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Test továrního nastavení se nezdařil"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Test FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nebyl nalezen žádný balíček umožňující test FACTORY_TEST."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné uživatelské jméno nebo heslo."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zapomněli jste uživatelské jméno nebo heslo?\nPřejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontrola účtu…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávný kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%d</xliff:g>× jste se neúspěšně pokusili odemknout televizi. Po dalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspěšných pokusech bude v televizi obnoveno tovární nastavení a veškerá uživatelská data budou ztracena."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste zadali nesprávný kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%1$d</xliff:g>× jste se neúspěšně pokusili odemknout televizi. Po dalších <xliff:g id="NUMBER_1">%2$d</xliff:g> neúspěšných pokusech bude v televizi obnoveno tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Již jste se <xliff:g id="NUMBER_0">%1$d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"<xliff:g id="NUMBER">%d</xliff:g>× jste se neúspěšně pokusili odemknout televizi. V televizi nyní bude obnoveno tovární nastavení."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"<xliff:g id="NUMBER_0">%d</xliff:g>× jste nesprávně načrtli bezpečnostní gesto. Po dalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspěšných pokusech budete požádáni o odemčení televize pomocí e-mailového účtu.\n\nOpakujte akci za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%2$d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"<xliff:g id="NUMBER_0">%1$d</xliff:g>× jste nesprávně načrtli bezpečnostní gesto. Po dalších <xliff:g id="NUMBER_1">%2$d</xliff:g> neúspěšných pokusech budete požádáni o odemčení televize pomocí e-mailového účtu.\n\nOpakujte akci za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odebrat"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Zvýšit hlasitost nad doporučenou úroveň?\n\nDlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 632f9bb..f83828f 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Se brugervejledningen, eller kontakt kundeservice."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortet er låst."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Låser SIM-kortet op ..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere forsøg vil du blive bedt om at låse din tablet op ved hjælp af dit Google-login\n\n  Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%d</xliff:g> mislykket forsøg bliver du bedt om at låse op for dit tv ved hjælp af din Google-login.\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> forsøg til vil du blive bedt om at låse din telefon op ved hjælp af dit Google-login.\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter yderligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har forsøgt at låse tv\'et forkert op <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøg nulstilles fjernsynet til fabriksindstillingerne, og alle brugerdata går tabt."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter yderligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> yderligere forsøg vil du blive bedt om at låse din tablet op ved hjælp af dit Google-login\n\n  Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykket forsøg bliver du bedt om at låse op for dit tv ved hjælp af din Google-login.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> forsøg til vil du blive bedt om at låse din telefon op ved hjælp af dit Google-login.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter yderligere <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har forsøgt at låse tv\'et forkert op <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg nulstilles fjernsynet til fabriksindstillingerne, og alle brugerdata går tabt."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter yderligere <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Tabletten nulstilles til fabriksindstillingerne."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Du har forsøgt at låse tv\'et forkert op <xliff:g id="NUMBER">%d</xliff:g> gange. Fjernsynet nulstilles nu til fabriksindstillingerne."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Telefonen nulstilles til fabriksindstillingerne."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ord"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linje"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabrikstest mislykkedes"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Handlingen FACTORY_TEST understøttes kun af pakker installeret i /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Der blev ikke fundet nogen pakke, som leverer handlingen FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldigt brugernavn eller ugyldig adgangskode."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt dit brugernavn eller din adgangskode?\nGå til "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontoen kontrolleres…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har forsøgt at låse tv\'et forkert op <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøg nulstilles fjernsynet til fabriksindstillingerne, og alle brugerdata går tabt."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> yderligere mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har forsøgt at låse tv\'et forkert op <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg nulstilles fjernsynet til fabriksindstillingerne, og alle brugerdata går tabt."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> yderligere mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Tabletten nulstilles til fabriksindstillingerne."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Du har forsøgt at låse tv\'et forkert op <xliff:g id="NUMBER">%d</xliff:g> gange. Fjernsynet nulstilles nu til fabriksindstillingerne."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Telefonen nulstilles til fabriksindstillingerne."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%d</xliff:g> mislykket forsøg bliver du bedt om at låse op for dit tv ved hjælp af en e-mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykket forsøg bliver du bedt om at låse op for dit tv ved hjælp af en e-mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Vil du skrue højere op end det anbefalede lydstyrkeniveau?\n\nDu kan skade hørelsen ved at lytte til meget højt musik over længere tid."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index df539cb..ea6239c 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Weitere Informationen erhalten Sie 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">%d</xliff:g>-mal falsch gezeichnet. \n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal falsch eingegeben.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal falsch eingegeben.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%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">%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">%d</xliff:g>-mal falsch gezeichnet. Wenn Sie es noch <xliff:g id="NUMBER_1">%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">%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">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%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">%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">%d</xliff:g> Mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Nach <xliff:g id="NUMBER_1">%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">%d</xliff:g> Mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"Wort"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"Link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"Zeile"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Werkstest fehlgeschlagen"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Die Aktion FACTORY_TEST wird nur für unter \"/system/app\" gespeicherte Pakete unterstützt."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Es wurden kein Paket mit der Aktion FACTORY_TEST gefunden."</string>
@@ -1285,18 +1283,18 @@
     <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_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">%d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal falsch gezeichnet. \n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal erfolglos versucht, den Fernseher zu entsperren. Nach <xliff:g id="NUMBER_1">%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">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</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">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%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">%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">%d</xliff:g>-mal falsch gezeichnet. Wenn Sie es noch <xliff:g id="NUMBER_1">%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">%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">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%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">%d</xliff:g> Sekunden erneut."</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_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>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8440c60..83ad7de 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Έχετε πληκτρολογήσει τον αριθμό σας PIN εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση της σύνδεσής σας Google.\n\n Προσπαθήστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Έχετε σχεδιάσει λανθασμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ακόμα μη επιτυχημένες προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε την τηλεόρασή σας χρησιμοποιώντας τη σύνδεση Google.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση της σύνδεσής σας Google.\n\n Προσπαθήστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Έχετε προσπαθήσει να ξεκλειδώσετε λανθασμένα την τηλεόραση <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ακόμα μη επιτυχημένες προσπάθειες, η τηλεόραση θα επανέλθει στις προεπιλεγμένες, εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%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> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση της σύνδεσής σας 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">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές. Το tablet θα επαναφερθεί στην εργοστασιακή προεπιλογή."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"λέξη"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"σύνδεσμος"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"γραμμή"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Η εργοστασιακή δοκιμή απέτυχε"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Η ενέργεια FACTORY_TEST υποστηρίζεται μόνο για πακέτα που είναι εγκατεστημένα στον κατάλογο /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Δεν βρέθηκε πακέτο που να παρέχει την ενέργεια FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ξεχάσατε το όνομα χρήστη ή τον κωδικό πρόσβασής σας;\nΕπισκεφτείτε τη διεύθυνση "<b>"google.com/accounts/recovery"</b>"."</string>
     <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">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλετπα."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Έχετε προσπαθήσει να ξεκλειδώσετε λανθασμένα την τηλεόραση <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ακόμα μη επιτυχημένες προσπάθειες, η τηλεόραση θα επανέλθει στις προεπιλεγμένες, εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το τηλέφωνο θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</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_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</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">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές. Το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις."</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">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Έχετε σχεδιάσει λανθασμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ακόμα μη επιτυχημένες προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε την τηλεόρασή σας χρησιμοποιώντας έναν λογαριασμό ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%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> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\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>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index f2b9c26..7ff1ef3 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"See the User Guide or contact Customer Care."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card is locked."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Unlocking SIM card…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"word"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"line"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f2b9c26..7ff1ef3 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"See the User Guide or contact Customer Care."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card is locked."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Unlocking SIM card…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"word"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"line"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f2b9c26..7ff1ef3 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"See the User Guide or contact Customer Care."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card is locked."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Unlocking SIM card…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using your Google signin.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"word"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"line"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the TV will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"You have incorrectly attempted to unlock the TV <xliff:g id="NUMBER">%d</xliff:g> times. The TV will now be reset to factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your TV using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 84e4753..bc05551 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guía del usuario o comunícate con el servicio de atención al cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La tarjeta SIM está bloqueada."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando tarjeta SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Estableciste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu tablet mediante el uso de tu información de acceso de Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Trazaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, tendrás que desbloquear la TV con tus datos de acceso a Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu dispositivo mediante el uso de tu información de acceso de Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tablet y se pierdan todos los datos de usuario."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Intentaste desbloquear la TV <xliff:g id="NUMBER_0">%d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se restablecerá la configuración de fábrica de la TV y se perderán todos los datos del usuario."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos de usuario."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Estableciste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu tablet mediante el uso de tu información de acceso de Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Trazaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, tendrás que desbloquear la TV con tus datos de acceso a Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu dispositivo mediante el uso de tu información de acceso de Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%2$d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tablet y se pierdan todos los datos de usuario."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Intentaste desbloquear la TV <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se restablecerá la configuración de fábrica de la TV y se perderán todos los datos del usuario."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%2$d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos de usuario."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica de la tablet."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Intentaste desbloquear la TV <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se restablecerá la configuración de fábrica de la TV."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del dispositivo."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"Palabra"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"Vínculo"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"Línea"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Error en la prueba de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"La acción FACTORY_TEST se admite solamente en paquetes instalados en /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No se ha encontrado ningún paquete que proporcione la acción FACTORY_TEST ."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nombre de usuario o contraseña incorrectos"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"¿Olvidaste tu nombre de usuario o contraseña?\nAccede a "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando la cuenta…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tablet y se pierdan todos los datos del usuario."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Intentaste desbloquear la TV <xliff:g id="NUMBER_0">%d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se restablecerá la configuración de fábrica de la TV y se perderán todos los datos del usuario."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos del usuario."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%2$d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tablet y se pierdan todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Intentaste desbloquear la TV <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se restablecerá la configuración de fábrica de la TV y se perderán todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%2$d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos del usuario."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica de la tablet."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Intentaste desbloquear la TV <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se restablecerá la configuración de fábrica de la TV."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del dispositivo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tablet mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Trazaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, tendrás que desbloquear la TV con una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tablet mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Trazaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, tendrás que desbloquear la TV con una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar a un alto volumen durante largos períodos puede dañar tu audición."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 1417ba4..aadf387 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guía del usuario o ponte en contacto con el servicio de atención al cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Introduce el código PIN."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando tarjeta SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación de un patrón de desbloqueo. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras  <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el tablet.\n\n Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Has dibujado el patrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, deberás desbloquear la TV iniciando sesión en Google.\n\n Vuelve a intentarlo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el teléfono.\n\n Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas <xliff:g id="NUMBER_1">%d</xliff:g> veces más, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Has intentado desbloquear la TV incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, la TV se restablecerá a los valores predeterminados de fábrica y se perderán todos los datos del usuario."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas <xliff:g id="NUMBER_1">%d</xliff:g> veces más, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has realizado <xliff:g id="NUMBER_0">%1$d</xliff:g> intentos fallidos de creación de un patrón de desbloqueo. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras  <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el tablet.\n\n Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Has dibujado el patrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, deberás desbloquear la TV iniciando sesión en Google.\n\n Vuelve a intentarlo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el teléfono.\n\n Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo has conseguido. Si fallas <xliff:g id="NUMBER_1">%2$d</xliff:g> veces más, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Has intentado desbloquear la TV incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, la TV se restablecerá a los valores predeterminados de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo has conseguido. Si fallas <xliff:g id="NUMBER_1">%2$d</xliff:g> veces más, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Has intentado desbloquear el tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Has intentando desbloquear la TV incorrectamente <xliff:g id="NUMBER">%d</xliff:g> veces. La TV se restablecerá a los valores predeterminados de fábrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"palabra"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"enlace"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"línea"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fallo en la prueba de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"La acción FACTORY_TEST solo es compatible con los paquetes instalados en /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No se ha encontrado ningún paquete que proporcione la acción FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"El nombre de usuario o la contraseña no son válidos."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Si has olvidado tu nombre de usuario o tu contraseña,\naccede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando cuenta…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar tu patrón de desbloqueo. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Has intentado desbloquear la TV incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, la TV se restablecerá a los valores predeterminados de fábrica y se perderán todos los datos del usuario."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar tu patrón de desbloqueo. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Has intentado desbloquear la TV incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, la TV se restablecerá a los valores predeterminados de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has intentado desbloquear el tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Has intentando desbloquear la TV incorrectamente <xliff:g id="NUMBER">%d</xliff:g> veces. La TV se restablecerá a los valores predeterminados de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Has dibujado el patrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, deberás desbloquear la TV mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Has dibujado el patrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, deberás desbloquear la TV mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%2$d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar sonidos a alto volumen durante largos períodos de tiempo puede dañar tus oídos."</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 802a597..4aed72d 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Vaadake kasutusjuhendit või võtke ühendust klienditeenindusega."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart on lukus."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaardi avamine ..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olete oma avamismustrit <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti koostanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Olete avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti joonistanud. Kui joonistate mustri veel <xliff:g id="NUMBER_1">%d</xliff:g> korda valesti, palutakse teil avada teler Google\'i sisselogimisandmete abil.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> edutut katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Teleri avamine on <xliff:g id="NUMBER_0">%d</xliff:g> korda ebaõnnestunud. Kui veel <xliff:g id="NUMBER_1">%d</xliff:g> katset ebaõnnestub, lähtestatakse teler tehaseseadetele ja kasutajaandmed lähevad kaotsi."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olete oma avamismustrit <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti koostanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olete parooli <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olete PIN-koodi <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Olete avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti joonistanud. Kui joonistate mustri veel <xliff:g id="NUMBER_1">%2$d</xliff:g> korda valesti, palutakse teil avada teler Google\'i sisselogimisandmete abil.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Olete üritanud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> edutut katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Teleri avamine on <xliff:g id="NUMBER_0">%1$d</xliff:g> korda ebaõnnestunud. Kui veel <xliff:g id="NUMBER_1">%2$d</xliff:g> katset ebaõnnestub, lähtestatakse teler tehaseseadetele ja kasutajaandmed lähevad kaotsi."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Olete üritanud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Teleri avamine on <xliff:g id="NUMBER">%d</xliff:g> korda ebaõnnestunud. Teler lähtestatakse tehaseseadetele."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"sõna"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"rida"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Tehasetest ebaõnnestus"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Toimingut FACTORY_TEST toetatakse ainult kausta \\system\\app installitud pakettide puhul."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Ei leitud ühtegi paketti, mis võimaldaks toimingut FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Vale kasutajanimi või parool."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kas unustasite kasutajanime või parooli?\nKülastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto kontrollimine ..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige uuesti <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Teleri avamine on <xliff:g id="NUMBER_0">%d</xliff:g> korda ebaõnnestunud. Kui veel <xliff:g id="NUMBER_1">%d</xliff:g> katset ebaõnnestub, lähtestatakse teler tehaseseadetele ja kasutajaandmed lähevad kaotsi."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti sisestanud.\n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti sisestanud. \n\nProovige uuesti <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti.\n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Olete üritanud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Teleri avamine on <xliff:g id="NUMBER_0">%1$d</xliff:g> korda ebaõnnestunud. Kui veel <xliff:g id="NUMBER_1">%2$d</xliff:g> katset ebaõnnestub, lähtestatakse teler tehaseseadetele ja kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Olete üritanud <xliff:g id="NUMBER_0">%1$d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Teleri avamine on <xliff:g id="NUMBER">%d</xliff:g> korda ebaõnnestunud. Teler lähtestatakse tehaseseadetele."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Olete avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti joonistanud. Kui joonistate mustri veel <xliff:g id="NUMBER_1">%d</xliff:g> korda valesti, siis palutakse teil avada teler meilikonto abil.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Olete avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti joonistanud. Kui joonistate mustri veel <xliff:g id="NUMBER_1">%2$d</xliff:g> korda valesti, siis palutakse teil avada teler meilikonto abil.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eemalda"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Kas suurendada helitugevuse taset üle soovitatud taseme?\n\nPikaajaline valju helitugevusega kuulamine võib kuulmist kahjustada."</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index b4e4a7b..9f10506 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Ikusi erabiltzailearen gida edo jarri bezeroarentzako arreta-zerbitzuarekin harremanetan."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM txartela blokeatuta dago."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM txartela desblokeatzen…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%d</xliff:g> segundo barru."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Pasahitza oker idatzi duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%d</xliff:g> segundo barru."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PINa oker idatzi duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%d</xliff:g> segundo barru."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz idazten baduzu oker, tableta desblokeatzeko, Google-n saioa hasteko kredentzialak erabiltzea eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%d</xliff:g> segundo barru."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz oker marrazten baduzu, Google-n saioa hasteko kredentzialak erabiltzea eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%d</xliff:g> segundo barru."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz idazten baduzu oker, telefonoa desblokeatzeko, Google-n saioa hasteko kredentzialak erabiltzea eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%d</xliff:g> segundo barru."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tableta <xliff:g id="NUMBER_0">%d</xliff:g> aldiz desblokeatzen saiatu zara. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz huts egiten baduzu, fabrikako ezarpen lehenetsiak berrezarriko dira eta datu guztiak galduko dituzu."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Telebista desblokeatzen saiatu zara, baina huts egin duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Datozen <xliff:g id="NUMBER_1">%d</xliff:g> saiakeretan ere huts egiten baduzu, jatorrizko ezarpen lehenetsiak berrezarriko dira telebistan eta erabiltzaile-datu guztiak galduko dira."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefonoa <xliff:g id="NUMBER_0">%d</xliff:g> aldiz desblokeatzen saiatu zara. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz huts egiten baduzu, fabrikako ezarpen lehenetsiak berrezarriko dira eta datu guztiak galduko dituzu."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Pasahitza oker idatzi duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PINa oker idatzi duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz idazten baduzu oker, tableta desblokeatzeko, Google-n saioa hasteko kredentzialak erabiltzea eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, Google-n saioa hasteko kredentzialak erabiltzea eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz idazten baduzu oker, telefonoa desblokeatzeko, Google-n saioa hasteko kredentzialak erabiltzea eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tableta <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz desblokeatzen saiatu zara. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, fabrikako ezarpen lehenetsiak berrezarriko dira eta datu guztiak galduko dituzu."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Telebista desblokeatzen saiatu zara, baina huts egin duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Datozen <xliff:g id="NUMBER_1">%2$d</xliff:g> saiakeretan ere huts egiten baduzu, jatorrizko ezarpen lehenetsiak berrezarriko dira telebistan eta erabiltzaile-datu guztiak galduko dira."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefonoa <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz desblokeatzen saiatu zara. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz huts egiten baduzu, fabrikako ezarpen lehenetsiak berrezarriko dira eta datu guztiak galduko dituzu."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tableta <xliff:g id="NUMBER">%d</xliff:g> aldiz desblokeatzen saiatu zara. Orain, fabrikako ezarpen lehenetsiak berrezarriko dira."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Telebista desblokeatzen saiatu zara, baina huts egin duzu <xliff:g id="NUMBER">%d</xliff:g> aldiz. Jatorrizko ezarpen lehenetsiak berrezarriko dira telebistan."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Telefonoa <xliff:g id="NUMBER">%d</xliff:g> aldiz desblokeatzen saiatu zara. Orain, fabrikako ezarpen lehenetsiak berrezarriko dira."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"hitza"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"esteka"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"lerroa"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabrikako probak huts egin du"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ekintza /system/app karpetan instalatuta dauden paketeetarako onartzen da soilik."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Ez da FACTORY_TEST ekintza hornitzen duen paketerik aurkitu."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Erabiltzaile-izen edo pasahitz baliogabea."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Erabiltzaile-izena edo pasahitza ahaztu zaizu?\nZoaz "<b>"google.com/accounts/recovery"</b>" helbidera."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontua egiaztatzen…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PINa oker idatzi duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%d</xliff:g> segundo barru."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Pasahitza oker idatzi duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%d</xliff:g> segundo barru."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%d</xliff:g> segundo barru."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tableta desblokeatzen saiatu zara <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> saiakera okerren ondoren, jatorrizko ezarpen lehenetsiak berrezarriko dira tabletan eta erabiltzaile-datu guztiak galduko dira."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Telebista desblokeatzen saiatu zara, baina huts egin duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Datozen <xliff:g id="NUMBER_1">%d</xliff:g> saiakeretan ere huts egiten baduzu, jatorrizko ezarpen lehenetsiak berrezarriko dira telebistan eta erabiltzaile-datu guztiak galduko dira."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefonoa desblokeatzen saiatu zara <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> saiakera okerren ondoren, jatorrizko ezarpen lehenetsiak berrezarriko dira telefonoan eta erabiltzaile-datu guztiak galduko dira."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PINa oker idatzi duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Pasahitza oker idatzi duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tableta desblokeatzen saiatu zara <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> saiakera okerren ondoren, jatorrizko ezarpen lehenetsiak berrezarriko dira tabletan eta erabiltzaile-datu guztiak galduko dira."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Telebista desblokeatzen saiatu zara, baina huts egin duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Datozen <xliff:g id="NUMBER_1">%2$d</xliff:g> saiakeretan ere huts egiten baduzu, jatorrizko ezarpen lehenetsiak berrezarriko dira telebistan eta erabiltzaile-datu guztiak galduko dira."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefonoa desblokeatzen saiatu zara <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> saiakera okerren ondoren, jatorrizko ezarpen lehenetsiak berrezarriko dira telefonoan eta erabiltzaile-datu guztiak galduko dira."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tableta desblokeatzen saiatu zara <xliff:g id="NUMBER">%d</xliff:g> aldiz. Jatorrizko ezarpen lehenetsiak berrezarriko dira."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Telebista desblokeatzen saiatu zara, baina huts egin duzu <xliff:g id="NUMBER">%d</xliff:g> aldiz. Jatorrizko ezarpen lehenetsiak berrezarriko dira telebistan."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefonoa desblokeatzen saiatu zara <xliff:g id="NUMBER">%d</xliff:g> aldiz. Jatorrizko ezarpen lehenetsiak berrezarriko dira."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz oker marrazten baduzu, tableta posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%d</xliff:g> segundo barru."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz oker marrazten baduzu, telebista posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%d</xliff:g> segundo barru."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%d</xliff:g> aldiz oker marrazten baduzu, telefonoa posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%d</xliff:g> segundo barru."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, tableta posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, telebista posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, telefonoa posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Kendu"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Bolumena gomendatutako mailatik gora igo nahi duzu?\n\nMusika bolumen handian eta denbora luzez entzuteak entzumena kalte diezazuke."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 39efbba..2a41913 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"لطفاً به راهنمای کاربر مراجعه کرده یا با مرکز پشتیبانی از مشتریان تماس بگیرید."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"سیم کارت قفل شد."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"بازگشایی قفل سیم کارت..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"‏الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"گذرواژهٔ خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کرده‌اید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"‏پین را<xliff:g id="NUMBER_0">%d</xliff:g>  بار اشتباه تایپ کرده‎اید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"‏شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که برای بازگشایی قفل رایانهٔ لوحی خود به Google وارد شوید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"‏الگوی بازگشایی را <xliff:g id="NUMBER_0">%d</xliff:g> دفعه به صورت نادرست رسم کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، از شما خواسته خواهد شد تا با استفاده از ورود به سیستم Google، قفل تلویزیون‌تان را باز کنید.\n\n پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه، دوباره امتحان کنید."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"‏الگوی قفل‌گشایی را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر از شما خواسته می‎شود که برای بازگشایی قفل گوشی خود به برنامه Google وارد شوید.\n\n پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل رایانهٔ لوحی کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"<xliff:g id="NUMBER_0">%d</xliff:g> دفعه به صورت نادرست سعی کرده‌اید قفل تلویزیون را باز کنید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، تلویزیون به تنظیمات پیش‌فرض کارخانه بازنشانی خواهد شد و اطلاعات کاربر از دست خواهد رفت."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از<xliff:g id="NUMBER_1">%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">"‏پین را<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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"شما به اشتباه اقدام به باز کردن قفل <xliff:g id="NUMBER">%d</xliff:g> رایانهٔ لوحی کرده‌اید. رایانهٔ لوحی در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"کلمه"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"پیوند"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"خط"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"تست کارخانه انجام نشد"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"‏عملکرد FACTORY_TEST تنها برای بسته‌های نصب شده در /system/app پشتیبانی می‌شود."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"‏بسته‌ای یافت نشد که عملکرد FACTORY_TEST را ارائه کند."</string>
@@ -783,7 +781,7 @@
     <string name="permlab_setAlarm" msgid="1379294556362091814">"تنظیم یک هشدار"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"‏به برنامه اجازه می‎دهد تا هشداری را در برنامه ساعت زنگدار نصب شده تنظیم کند. برخی از برنامه‎های ساعت زنگدار نمی‌‎توانند این ویژگی را اعمال کنند."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"افزودن پست صوتی"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"به برنامه اجازه می‌دهد تا پیام‌ها را به صندوق دریافت پست صوتی شما اضافه کند."</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"به برنامه اجازه می‌دهد تا پیام‌ها را به صندوق ورودی پست صوتی شما اضافه کند."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"تغییر مجوزهای مکان جغرافیایی مرورگر"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"‏به برنامه اجازه می‎دهد تا مجوزهای جغرافیایی مرورگر را تغییر دهد. برنامه‎های مخرب می‎توانند از آن استفاده کنند تا اطلاعات موقعیت مکانی را به سایت‌های وب کتابخانه بفرستند."</string>
     <string name="save_password_message" msgid="767344687139195790">"می‌خواهید مرورگر این گذرواژه را به خاطر داشته باشد؟"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"نام کاربری یا گذرواژه نامعتبر."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"‏نام کاربری یا گذرواژه خود را فراموش کردید؟\nاز "<b>"google.com/accounts/recovery"</b>" بازدید کنید."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"درحال بررسی حساب..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"پین خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"گذرواژه خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%d</xliff:g> دفعه به صورت نادرست سعی کرده‌اید قفل تلویزیون را باز کنید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، تلویزیون به تنظیمات پیش‌فرض کارخانه بازنشانی خواهد شد و اطلاعات کاربر از دست خواهد رفت."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، تلفن به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"پین خود را <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_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">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"الگوی بازگشایی‌تان را <xliff:g id="NUMBER_0">%d</xliff:g> دفعه به صورت نادرست رسم کرده‌اید. <xliff:g id="NUMBER_1">%d</xliff:g> پس از \n تلاش ناموفق دیگر، از شما خواسته می‌شود تا با استفاده از یک حساب ایمیل، قفل تلویزیون‌تان را باز کنید.\n پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"‏شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 022e0a6..b83307e 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Katso ohjeita käyttöoppaasta tai ota yhteyttä asiakaspalveluun."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortti on lukittu."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kortin lukitusta poistetaan…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus Google-sisäänkirjautumisen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan television lukitus Google-käyttäjätunnuksen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus Google-sisäänkirjautumisen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Television lukituksen poistaminen on epäonnistunut <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos se epäonnistuu vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, television tehdasasetukset palautetaan ja käyttäjätiedot poistetaan."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus Google-sisäänkirjautumisen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään poistamaan television lukitus Google-käyttäjätunnuksen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus Google-sisäänkirjautumisen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Television lukituksen poistaminen on epäonnistunut <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos se epäonnistuu vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, television tehdasasetukset palautetaan ja käyttäjätiedot poistetaan."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Laitteeseen palautetaan nyt tehdasasetukset."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Television lukituksen poistaminen on epäonnistunut <xliff:g id="NUMBER">%d</xliff:g> kertaa. Television tehdasasetukset palautetaan."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Puhelimeen palautetaan nyt tehdasasetukset."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"sana"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"linkki"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"rivi"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Tehdastesti epäonnistui"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST-toimintoa tuetaan vain paketeille, jotka on tallennettu kansioon /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST-toiminnon tarjoavaa pakettia ei löytynyt."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Virheellinen käyttäjänimi tai salasana."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Unohditko käyttäjänimesi tai salasanasi?\nKäy osoitteessa "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Tarkistetaan tiliä..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Television lukituksen poistaminen on epäonnistunut <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos se epäonnistuu vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, television tehdasasetukset palautetaan ja käyttäjätiedot poistetaan."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Television lukituksen poistaminen on epäonnistunut <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos se epäonnistuu vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, television tehdasasetukset palautetaan ja käyttäjätiedot poistetaan."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Laitteeseen palautetaan nyt tehdasasetukset."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Television lukituksen poistaminen on epäonnistunut <xliff:g id="NUMBER">%d</xliff:g> kertaa. Television tehdasasetukset palautetaan."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Puhelimeen palautetaan nyt tehdasasetukset."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään avaamaan television lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan television lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Poista"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Nostetaanko äänenvoimakkuus suositellun tason yläpuolelle?\n\nPitkäkestoinen kova äänenvoimakkuus saattaa heikentää kuuloa."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 1452779..6f54ece 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Veuillez consulter le guide utilisateur ou contacter le service à la clientèle."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La carte SIM est verrouillée."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Déverrouillage de la carte SIM en cours…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Vous avez tracé incorrectement votre schéma de déverrouillage <xliff:g id="NUMBER_0">%d</xliff:g> fois. Après <xliff:g id="NUMBER_1">%d</xliff:g> autres tentatives infructueuses, vous devrez déverrouiller votre téléviseur en vous connectant à votre compte Google.\n\nEssayez à nouveau dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Vous avez effectué <xliff:g id="NUMBER_0">%d</xliff:g> tentative(s) pour déverrouiller le téléviseur. Après <xliff:g id="NUMBER_1">%d</xliff:g> tentatives infructueuses, le téléviseur sera réinitialisé aux paramètres d\'usine et toutes les données d\'utilisateur seront perdues."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Vous avez tracé incorrectement votre schéma de déverrouillage <xliff:g id="NUMBER_0">%1$d</xliff:g> fois. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autres tentatives infructueuses, vous devrez déverrouiller votre téléviseur en vous connectant à votre compte Google.\n\nEssayez à nouveau dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Vous avez effectué <xliff:g id="NUMBER_0">%1$d</xliff:g> tentative(s) pour déverrouiller le téléviseur. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentatives infructueuses, le téléviseur sera réinitialisé aux paramètres d\'usine et toutes les données d\'utilisateur seront perdues."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Vous avez effectué <xliff:g id="NUMBER">%d</xliff:g> tentatives infructueuses pour déverrouiller le téléviseur. Le téléviseur va maintenant être réinitialisé aux paramètres d\'usine."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"mot"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"Lié"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ligne"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Échec du test usine"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'utilisateur ou mot de passe non valide."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Vérification du compte en cours…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Vous avez effectué <xliff:g id="NUMBER_0">%d</xliff:g> tentative(s) pour déverrouiller le téléviseur. Après <xliff:g id="NUMBER_1">%d</xliff:g> tentatives infructueuses, le téléviseur sera réinitialisé aux paramètres d\'usine et toutes les données d\'utilisateur seront perdues."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Vous avez effectué <xliff:g id="NUMBER_0">%1$d</xliff:g> tentative(s) pour déverrouiller le téléviseur. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> tentatives infructueuses, le téléviseur sera réinitialisé aux paramètres d\'usine et toutes les données d\'utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Vous avez effectué <xliff:g id="NUMBER">%d</xliff:g> tentatives infructueuses pour déverrouiller le téléviseur. Le téléviseur va maintenant être réinitialisé aux paramètres d\'usine."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Vous avez tracé incorrectement votre schéma de déverrouillage <xliff:g id="NUMBER_0">%d</xliff:g> fois. Après <xliff:g id="NUMBER_1">%d</xliff:g> autres tentatives infructueuses, vous devrez déverrouiller votre téléviseur à l\'aide d\'un compte de courriel.\n\nEssayez à nouveau dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Vous avez tracé incorrectement votre schéma de déverrouillage <xliff:g id="NUMBER_0">%1$d</xliff:g> fois. Après <xliff:g id="NUMBER_1">%2$d</xliff:g> autres tentatives infructueuses, vous devrez déverrouiller votre téléviseur à l\'aide d\'un compte de courriel.\n\nEssayez à nouveau dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Augmenter le volume au-dessus du niveau recommandé?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 1c36382..7a7a814 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -420,7 +420,7 @@
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Autoriser l\'application à utiliser le matériel d\'empreintes digitales pour l\'authentification"</string>
     <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Empreinte numérique partiellement détectée. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossible de reconnaître l\'empreinte numérique. Veuillez réessayer."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le capteur d\'empreintes numériques est sale. Veuillez le nettoyer, puis réessayer."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le lecteur d\'empreintes numériques est sale. Veuillez le nettoyer, puis réessayer."</string>
     <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Vous avez déplacé votre doigt trop rapidement. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Veuillez consulter le guide utilisateur ou contacter le service client."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La carte SIM est verrouillée."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Déblocage de la carte SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Vous avez saisi un mot de passe incorrect <xliff:g id="NUMBER_0">%d</xliff:g> fois. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Vous avez saisi un code PIN incorrect <xliff:g id="NUMBER_0">%d</xliff:g> fois. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Cela fait <xliff:g id="NUMBER_0">%d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller le téléviseur en vous connectant à votre compte Google.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Cela fait <xliff:g id="NUMBER_0">%d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, la configuration d\'usine du téléviseur sera rétablie, et vous perdrez toutes les données utilisateur."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Vous avez saisi un mot de passe incorrect <xliff:g id="NUMBER_0">%1$d</xliff:g> fois. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Vous avez saisi un code PIN incorrect <xliff:g id="NUMBER_0">%1$d</xliff:g> fois. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Cela fait <xliff:g id="NUMBER_0">%1$d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller le téléviseur en vous connectant à votre compte Google.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%2$d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Cela fait <xliff:g id="NUMBER_0">%1$d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, la configuration d\'usine du téléviseur sera rétablie, et vous perdrez toutes les données utilisateur."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Cela fait <xliff:g id="NUMBER">%d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Sa configuration d\'usine va être rétablie."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"mot"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"lien"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ligne"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Échec du test usine"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'utilisateur ou mot de passe non valide."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Vérification du compte en cours…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un code PIN incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Cela fait <xliff:g id="NUMBER_0">%d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, la configuration d\'usine du téléviseur sera rétablie, et vous perdrez toutes les données utilisateur."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un code PIN incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Cela fait <xliff:g id="NUMBER_0">%1$d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, la configuration d\'usine du téléviseur sera rétablie, et vous perdrez toutes les données utilisateur."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Cela fait <xliff:g id="NUMBER">%d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Sa configuration d\'usine va être rétablie."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Cela fait <xliff:g id="NUMBER_0">%d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller le téléviseur à l\'aide d\'un compte de messagerie.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Cela fait <xliff:g id="NUMBER_0">%1$d</xliff:g> fois que votre tentative de déverrouillage du téléviseur échoue. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller le téléviseur à l\'aide d\'un compte de messagerie.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Augmenter le volume au dessus du niveau recommandé ?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index eafcad7..ab24047 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta a guía do usuario ou ponte en contacto co servizo de asistencia ao cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"A tarxeta SIM está bloqueada."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando tarxeta SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Introduciches o contrasinal incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Introduciches o PIN incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, terás que desbloquear o tablet cos datos de inicio de sesión de Google.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, terás que desbloquear a televisión cos datos de inicio de sesión de Google.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono cos datos de inicio de sesión de Google.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tentaches desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%d</xliff:g> intentos máis sen logralo, restablecerase a configuración de fábrica predeterminada e perderanse todos os datos de usuario."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Tentaches desbloquear a televisión <xliff:g id="NUMBER_0">%d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, restableceranse os valores de fábrica do aparello e perderanse todos os datos de usuario."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%d</xliff:g> intentos máis sen logralo, restablecerase a configuración de fábrica predeterminada e perderanse todos os datos do usuario."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Introduciches o contrasinal incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Introduciches o PIN incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o tablet cos datos de inicio de sesión de Google.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear a televisión cos datos de inicio de sesión de Google.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono cos datos de inicio de sesión de Google.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tentaches desbloquear o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos máis sen logralo, restablecerase a configuración de fábrica predeterminada e perderanse todos os datos de usuario."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Tentaches desbloquear a televisión <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, restableceranse os valores de fábrica do aparello e perderanse todos os datos de usuario."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos máis sen logralo, restablecerase a configuración de fábrica predeterminada e perderanse todos os datos do usuario."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tentaches desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> veces sen conseguilo. Restablecerase a configuración de fábrica predeterminada."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Tentaches desbloquear a televisión <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Agora restableceranse os valores de fábrica do aparello."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces sen conseguilo. Restablecerase a configuración de fábrica predeterminada."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"palabra"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ligazón"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"liña"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Produciuse un erro durante a proba de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"A acción FACTORY_TEST só é compatible cos paquetes instalados en /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Non se atopou ningún paquete que forneza a acción FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"O nome de usuario ou o contrasinal non son válidos."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueciches o teu nome de usuario ou contrasinal?\nVisita a páxina "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando a conta..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Introduciches o PIN incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Introduciches o contrasinal incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tentaches desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%d</xliff:g> intentos máis sen logralo, restablecerase á configuración de fábrica predeterminada e perderanse todos os datos do usuario."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Tentaches desbloquear a televisión <xliff:g id="NUMBER_0">%d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, restableceranse os valores de fábrica do aparello e perderanse todos os datos de usuario."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%d</xliff:g> intentos máis sen logralo, restablecerase a configuración de fábrica predeterminada e perderanse todos os datos do usuario."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Introduciches o PIN incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Introduciches o contrasinal incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tentaches desbloquear o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos máis sen logralo, restablecerase á configuración de fábrica predeterminada e perderanse todos os datos do usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Tentaches desbloquear a televisión <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, restableceranse os valores de fábrica do aparello e perderanse todos os datos de usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER_0">%1$d</xliff:g> veces sen conseguilo. Se se realizan <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos máis sen logralo, restablecerase a configuración de fábrica predeterminada e perderanse todos os datos do usuario."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tentouse desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> veces sen conseguilo. Agora, restablecerase á configuración de fábrica predeterminada."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Tentaches desbloquear a televisión <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Agora restableceranse os valores de fábrica do aparello."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces sen conseguilo. Agora, restablecerase á configuración de fábrica predeterminada."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, terás que desbloquear o tablet a través dunha unha conta de correo electrónico.\n\n Téntao de novo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, terás que desbloquear a televisión cunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o tablet a través dunha unha conta de correo electrónico.\n\n Téntao de novo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear a televisión cunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Queres subir o volume máis do nivel recomendado?\n\nA reprodución de son a un volume elevado durante moito tempo pode provocar danos nos oídos."</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index e4c968d..93faa70 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> વખત ખોટી રીતે તમારી અનલૉક પેટર્ન દોરી. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે તમારો પાસવર્ડ લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે તમારો PIN લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ટેબ્લેટને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ટીવીને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ફોનને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"તમે ટેબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટેબ્લેટને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"તમે ટીવીને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટીવીને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%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">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો PIN લખ્યો છે. \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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ટેબ્લેટને અનલૉક કરવાનો પ્રયાસ કર્યો. ટેબ્લેટ હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"શબ્દ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"લિંક કરો"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"લાઇન"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ફેક્ટરી પરીક્ષણ નિષ્ફળ થયું"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ક્રિયા ફક્ત /system/app માં ઇન્સ્ટોલ કરેલા પૅકેજીસ માટે જ સમર્થિત છે."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST ક્રિયા પ્રદાન કરનાર કોઈ પૅકેજ મળ્યું નહોતું."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"અમાન્ય વપરાશકર્તાનામ અથવા પાસવર્ડ"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"તમારું વપરાશકર્તાનામ અથવા પાસવર્ડ ભૂલાઈ ગયો?\n "<b>"google.com/accounts/recovery"</b>" ની મુલાકાત લો."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"એકાઉન્ટ તપાસી રહ્યું છે…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે તમારો PIN લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે તમારો પાસવર્ડ લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે તમારી અનલૉક પેટર્ન દોરી. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"તમે ટેબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટેબ્લેટને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"તમે ટીવીને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટીવીને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%d</xliff:g> વધુ અસફળ પ્રયાસો પછી, ફોનને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો PIN લખ્યો છે. \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_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">%d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%d</xliff:g> વખત અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટેબ્લેટને અનલૉક કરવા માટે પૂછવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"તમે <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે અનલૉક પેટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%d</xliff:g> વખત અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટીવીને અનલૉક કરવા માટે પૂછવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"તમે તમારી અનલૉક પેટર્ન <xliff:g id="NUMBER_0">%d</xliff:g> વખત ખોટી રીતે દોરી. હજી <xliff:g id="NUMBER_1">%d</xliff:g> અસફળ પ્રયાસ પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને ફોનને અનલૉક કરવાનું કહેવામાં આવશે.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index d0e33bb..6dba1fb 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"कृपया उपयोगकर्ता मार्गदर्शिका देखें या ग्राहक सहायता से संपर्क करें."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"सिम कार्ड लॉक किया गया है."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"सिम कार्ड अनलॉक कर रहा है…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"आपने अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिखा है. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"आपने अपना पिन <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिखा है. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में फिर से प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके टेबलेट को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"आपने अपना अनलॉक पैटन <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टीवी को अपने Google साइन-इन का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके फ़ोन को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आप गलत तरीके से टेबलेट को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, टेबलेट फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"आपने टीवी को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, टीवी को फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आप गलत तरीके से फ़ोन को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%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">"आपने अपना पिन <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"आप टेबलेट को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. टेबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"शब्द"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"लिंक"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"पंक्ति"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"फ़ैक्‍ट्री परीक्षण विफल"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया केवल /system/app में इंस्‍टॉल किए गए पैकेज के लिए समर्थित है."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"ऐसा कोई पैकेज नहीं मिला था जो FACTORY_TEST कार्रवाई प्रदान करता हो."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"अमान्य उपयोगकर्ता नाम या पासवर्ड."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"अपना उपयोगकर्ता नाम या पासवर्ड भूल गए?\n "<b>"google.com/accounts/recovery"</b>" पर जाएं."</string>
     <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">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आप टेबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, टेबलेट फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"आपने टीवी को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, टीवी को फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट कर दिया जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, फ़ोन फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</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_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">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"आपने अपना अनलॉक पैटर्न <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से बनाया है. और <xliff:g id="NUMBER_1">%d</xliff:g> असफल प्रयासों के बाद, आपसे अपने टीवी को किसी ईमेल पते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index ce7155a..643cf0d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -683,15 +683,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Pogledajte korisnički priručnik ili kontaktirajte korisničku službu."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kartica je zaključana."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Otključavanje SIM kartice…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> zamolit ćemo vas da otključate tabletno računalo putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Iscrtali ste netočan uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja, morat ćete otključati televizor putem Google prijave.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Neispravno ste pokušali otključati tabletno računalo ovoliko puta: <xliff:g id="NUMBER_0">%d</xliff:g>. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Pokušali ste otključati TV <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja, TV će se vratiti na tvorničke postavke i izgubiti sve podatke korisnika."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Neispravno ste pokušali otključati telefon ovoliko puta: <xliff:g id="NUMBER_0">%d</xliff:g>. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> zamolit ćemo vas da otključate tabletno računalo putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Iscrtali ste netočan uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja, morat ćete otključati televizor putem Google prijave.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> morat ćete otključati telefon putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Neispravno ste pokušali otključati tabletno računalo ovoliko puta: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Pokušali ste otključati TV <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja, TV će se vratiti na tvorničke postavke i izgubiti sve podatke korisnika."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Neispravno ste pokušali otključati telefon ovoliko puta: <xliff:g id="NUMBER_0">%1$d</xliff:g>. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Neispravno ste pokušali otključati tabletno računalo ovoliko puta: <xliff:g id="NUMBER">%d</xliff:g>. Sada će biti vraćeno na tvorničke postavke."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Pokušali ste otključati televizor <xliff:g id="NUMBER">%d</xliff:g> puta. Televizor će se sada vratiti na tvorničke postavke."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Neispravno ste pokušali otključati telefon ovoliko puta: <xliff:g id="NUMBER">%d</xliff:g>. Sada će biti vraćen na tvorničke postavke."</string>
@@ -743,8 +743,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"riječ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"veza"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"redak"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Tvorničko testiranje nije uspjelo"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Radnja FACTORY_TEST podržana je samo za pakete instalirane na /sustavu/aplikaciji."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nije pronađen paket koji sadrži radnju FACTORY_TEST."</string>
@@ -1293,18 +1291,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nevažeće korisničko ime ili zaporka."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zaboravili ste korisničko ime ili zaporku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Provjera računa..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Pokušali ste otključati televizor <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja, televizor će se vratiti na tvorničke postavke i izgubiti sve podatke korisnika."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%d</xliff:g> puta. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Pokušali ste otključati televizor <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja, televizor će se vratiti na tvorničke postavke i izgubiti sve podatke korisnika."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Pokušali ste otključati televizor <xliff:g id="NUMBER">%d</xliff:g> puta. Televizor će se sada vratiti na tvorničke postavke."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Iscrtali ste netočan uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja, morat ćete otključati televizor putem računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Iscrtali ste netočan uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako ne uspijete ni nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja, morat ćete otključati televizor putem računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite li pojačati zvuk iznad preporučene razine?\n\nDugotrajno slušanje glasne glazbe može vam oštetiti sluh."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 37146e8..a6fdad3 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Nézze meg a felhasználói útmutatót, vagy vegye fel a kapcsolatot az ügyfélszolgálattal."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"A SIM kártya le van zárva."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM kártya feloldása..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nKérjük, <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva próbálja újra."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ön helytelenül adta meg a jelszót <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. \n \n Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ön <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n \n Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a táblagépét.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a feloldási mintát. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen kísérlet esetén a rendszer arra kéri majd, hogy Google-hoz használt bejelentkezési adataival oldja fel a tévét.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> másodpercen belül ismét próbálkozhat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"A táblagépet <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal sikertelenül próbálta feloldani a tévét. A tévé <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen kísérlet esetén visszaáll a gyári alapbeállításokra, és minden felhasználói adat elvész."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"A telefont <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nKérjük, <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva próbálja újra."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ön helytelenül adta meg a jelszót <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal. \n \n Próbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ön <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n \n Próbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a táblagépét.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg a feloldási mintát. <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen kísérlet esetén a rendszer arra kéri majd, hogy Google-hoz használt bejelentkezési adataival oldja fel a tévét.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> másodpercen belül ismét próbálkozhat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"A táblagépet <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal sikertelenül próbálta feloldani a tévét. A tévé <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen kísérlet esetén visszaáll a gyári alapbeállításokra, és minden felhasználói adat elvész."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"A telefont <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"A táblagépet <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a táblagép gyári alapértelmezett beállításait."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal sikertelenül próbálta feloldani a tévét. A tévé most visszaáll a gyári alapbeállításokra."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"A telefont <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a telefon gyári alapértelmezett beállításait."</string>
@@ -699,7 +699,7 @@
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Fiók feloldása"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Túl sok mintarajzolási próbálkozás"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"A feloldáshoz jelentkezzen be Google-fiókjával."</string>
-    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Felhasználónév (e-mail cím)"</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Felhasználónév (e-mail-cím)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Jelszó"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Bejelentkezés"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Érvénytelen felhasználónév vagy jelszó."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"szó"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"sor"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"A gyári teszt sikertelen"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"A FACTORY_TEST művelet csak a /system/app könyvtárba telepített csomagok esetében használható."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nem található olyan csomag, amely tartalmazná a FACTORY_TEST műveletet."</string>
@@ -1279,24 +1277,24 @@
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"A PIN kódok nem egyeznek."</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Túl sok mintarajzolási próbálkozás"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"A feloldáshoz jelentkezzen be Google-fiókjával."</string>
-    <string name="kg_login_username_hint" msgid="5718534272070920364">"Felhasználónév (e-mail cím)"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Felhasználónév (e-mail-cím)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Jelszó"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Bejelentkezés"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Érvénytelen felhasználónév vagy jelszó."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Elfelejtette a felhasználónevét vagy jelszavát?\nKeresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Fiók ellenőrzése..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a jelszót. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"A táblagépet <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal sikertelenül próbálta feloldani a tévét. A tévé <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen kísérlet esetén visszaáll a gyári alapbeállításokra, és minden felhasználói adat elvész."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"A telefont <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg a jelszót. \n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"A táblagépet <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal sikertelenül próbálta feloldani a tévét. A tévé <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen kísérlet esetén visszaáll a gyári alapbeállításokra, és minden felhasználói adat elvész."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"A telefont <xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"A táblagépet <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a táblagép gyári alapértelmezett beállításait."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal sikertelenül próbálta feloldani a tévét. A tévé most visszaáll a gyári alapbeállításokra."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"A telefont <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a telefon gyári alapértelmezett beállításait."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a feloldási mintát. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen kísérlet esetén a rendszer arra kéri majd, hogy e-mail fiók használatával oldja fel a tévét.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> másodpercen belül ismét próbálkozhat."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg a feloldási mintát. <xliff:g id="NUMBER_1">%2$d</xliff:g> további sikertelen kísérlet esetén a rendszer arra kéri majd, hogy e-mail fiók használatával oldja fel a tévét.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> másodpercen belül ismét próbálkozhat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eltávolítás"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Az ajánlott szint fölé szeretné emelni a hangerőt?\n\nHa hosszú időn át teszi ki magát nagy hangerőnek, azzal károsíthatja a hallását."</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 78641ad..e829a76 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\n Փորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր գրասալիկը` օգտագործելով ձեր Google-ի մուտքի օգտանունը:\n \n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք գծել ապակողպման նախշը: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո հեռուստացույցը կկարողանաք ապակողպել միայն մուտք գործելով ձեր Google հաշիվ:\n\n Նորից փորձեք <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով Google-ի ձեր մուտքը:\n \n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ գրասալիկն ապակողպելու սխալ փորձ եք արել: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Դուք հեռուստացույցն ապակողպելու <xliff:g id="NUMBER_0">%d</xliff:g> սխալ փորձ եք կատարել: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո հեռուստացույցի գործարանային կարգավորումները կվերականգնվեն և օգտվողի բոլոր տվյալները կջնջվեն:"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ հեռախոսը ապակողպելու սխալ փորձ եք արել: Եվս <xliff:g id="NUMBER_1">%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">"Դուք <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Դուք <xliff:g id="NUMBER">%d</xliff:g> անգամ սխալ փորձ եք արել գրասալիկն ապակողպելու համար: Գրասալիկն այժմ կվերակարգավորվի գործարանային լռելյայնի:"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"բառ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"հղում"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"գիծ"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Գործարանային թեստը ձախողվեց"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST գործողությունը միայն աջակցվում է /համակարգում/ծրագրում տեղադրված փաթեթների համար:"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Չի գտնվել ոչ մի փաթեթ, որը ապահովում է FACTORY_TEST գործողությունը:"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Սխալ օգտանուն կամ գաղտնաբառ:"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Մոռացե՞լ եք ձեր օգտանունը կամ գաղտնաբառը:\nԱյցելեք "<b>"google.com /accounts/recovery"</b>":"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Հաշիվը ստուգվում է..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել գրասալիկն ապակողպելու համար: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Դուք հեռուստացույցն ապակողպելու <xliff:g id="NUMBER_0">%d</xliff:g> սխալ փորձ եք կատարել: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո հեռուստացույցի գործարանային կարգավորումները կվերականգնվեն և օգտվողի բոլոր տվյալները կջնջվեն:"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել հեռախոսն ապակողպելու համար: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո հեռախոսը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Դուք <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \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_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">%d</xliff:g> անգամ: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել ձեր գրասալիկը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք գծել ապակողպման նախշը: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո հեռուստացույցը կկարողանաք ապակողպել միայն էլփոստի հաշվի միջոցով:\n\n Նորից փորձեք <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման նմուշը: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index d405e7a..f626389 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Lihatlah Panduan Pengguna atau hubungi Layanan Pelanggan."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kartu SIM terkunci."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Membuka kartu SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Sudah <xliff:g id="NUMBER_0">%d</xliff:g> kali Anda salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta untuk membuka kunci TV menggunakan info masuk Google.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Sudah <xliff:g id="NUMBER_0">%d</xliff:g> kali Anda berupaya membuka kunci TV dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya yang tidak berhasil, TV akan dikembalikan ke setelan default pabrik dan semua data pengguna akan hilang."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta untuk membuka kunci TV menggunakan info masuk Google.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci TV dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, TV akan dikembalikan ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci TV dengan tidak benar. TV sekarang akan dikembalikan ke setelan default pabrik."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"kata"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"tautan"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"baris"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Uji pabrik gagal"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Tindakan FACTORY_TEST hanya didukung untuk paket yang terpasang pada /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Tidak ada paket yang memberikan tindakan FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau sandi tidak valid."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau sandi Anda?\nKunjungi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Memeriksa akun…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Sudah <xliff:g id="NUMBER_0">%d</xliff:g> kali Anda berupaya membuka kunci TV dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya yang tidak berhasil, TV akan dikembalikan ke setelan default pabrik dan semua data pengguna akan hilang."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda berupaya membuka kunci TV dengan tidak benar. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, TV akan dikembalikan ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Sudah <xliff:g id="NUMBER">%d</xliff:g> kali Anda berupaya membuka kunci TV dengan tidak benar. TV sekarang akan dikembalikan ke setelan default pabrik."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Sudah <xliff:g id="NUMBER_0">%d</xliff:g> kali Anda salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta untuk membuka kunci TV menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Sudah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali Anda salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta untuk membuka kunci TV menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Hapus"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Mengeraskan volume di atas tingkat yang disarankan?\n\nMendengarkan dengan volume keras dalam waktu yang lama dapat merusak pendengaran Anda."</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index ef79b40..3ebbad7 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Skoðaðu notendahandbókina eða hafðu samband við þjónustudeild."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortið er læst."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Tekur SIM-kort úr lás…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndur."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Þú hefur slegið inn rangt aðgangsorð <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndur."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Þú hefur slegið inn rangt PIN-númer <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndur."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Þú hefur teiknað opnunarmynstrið rangt <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður beðið um að þú notir Google innskráningu til að opna spjaldtölvuna.\n\n Prófaðu aftur eftir <xliff:g id="NUMBER_2">%d</xliff:g> sekúndur."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. Ef þú teiknar rangt mynstur í <xliff:g id="NUMBER_1">%d</xliff:g> skipti í viðbót verður beðið um að þú skráir þig inn á Google til að opna fyrir sjónvarpið.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%d</xliff:g> sekúndur."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Þú hefur teiknað opnunarmynstrið rangt <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður beðið um að þú notir Google innskráningu til að opna símann.\n\n Prófaðu aftur eftir <xliff:g id="NUMBER_2">%d</xliff:g> sekúndur."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Þú hefur gert <xliff:g id="NUMBER_0">%d</xliff:g> tilraunir til að taka spjaldtölvuna úr lás. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður spjaldtölvan stillt á sjálfgefnar stillingar og öll notandagögn hennar glatast."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Þú hefur gert <xliff:g id="NUMBER_0">%d</xliff:g> árangurslausar tilraunir til að taka sjónvarpið úr lás. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> skipti í viðbót án árangurs verður sjónvarpið stillt á verksmiðjustillingar og þú glatar öllum notandagögnum."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Þú hefur gert <xliff:g id="NUMBER_0">%d</xliff:g> tilraunir til að taka símann úr lás. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður síminn stilltur á sjálfgefnar stillingar og öll notandagögn hans glatast."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Þú hefur slegið inn rangt aðgangsorð <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Þú hefur slegið inn rangt PIN-númer <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Þú hefur teiknað opnunarmynstrið rangt <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður beðið um að þú notir Google innskráningu til að opna spjaldtölvuna.\n\n Prófaðu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Ef þú teiknar rangt mynstur í <xliff:g id="NUMBER_1">%2$d</xliff:g> skipti í viðbót verður beðið um að þú skráir þig inn á Google til að opna fyrir sjónvarpið.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Þú hefur teiknað opnunarmynstrið rangt <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður beðið um að þú notir Google innskráningu til að opna símann.\n\n Prófaðu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> tilraunir til að taka spjaldtölvuna úr lás. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður spjaldtölvan stillt á sjálfgefnar stillingar og öll notandagögn hennar glatast."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að taka sjónvarpið úr lás. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> skipti í viðbót án árangurs verður sjónvarpið stillt á verksmiðjustillingar og þú glatar öllum notandagögnum."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> tilraunir til að taka símann úr lás. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður síminn stilltur á sjálfgefnar stillingar og öll notandagögn hans glatast."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> tilraunir til að taka spjaldtölvuna úr lás. Spjaldtölvan verður nú stillt á sjálfgefnar stillingar."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að taka sjónvarpið úr lás. Sjónvarpið verður nú stillt aftur á verksmiðjustillingar."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> tilraunir til að taka símann úr lás. Síminn verður nú stilltur á sjálfgefnar stillingar."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"orð"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"tengill"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"lína"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Verksmiðjuprófun mistókst"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Aðgerðin FACTORY_TEST er aðeins studd fyrir pakka sem settir eru upp í /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Enginn pakki fannst sem gefur kost á aðgerðinni FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ógilt notandanafn eða aðgangsorð."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Gleymdirðu notandanafninu eða aðgangsorðinu?\nFarðu á "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Athugar reikninginn…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Þú hefur slegið inn rangt PIN-númer <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndur."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Þú hefur slegið inn rangt aðgangsorð <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndur."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndur."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Þú hefur gert <xliff:g id="NUMBER_0">%d</xliff:g> tilraunir til að opna spjaldtölvuna. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður tölvan stillt á sjálfgefar stillingar og öll notandagögn hennar glatast."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Þú hefur gert <xliff:g id="NUMBER_0">%d</xliff:g> árangurslausar tilraunir til að taka sjónvarpið úr lás. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> skipti í viðbót án árangurs verður sjónvarpið stillt á verksmiðjustillingar og þú glatar öllum notandagögnum."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Þú hefur gert <xliff:g id="NUMBER_0">%d</xliff:g> tilraunir til að opna símann. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður síminn stilltur á sjálfgefnar stillingar og öll notandagögn hans glatast."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Þú hefur slegið inn rangt PIN-númer <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Þú hefur slegið inn rangt aðgangsorð <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> tilraunir til að opna spjaldtölvuna. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður tölvan stillt á sjálfgefar stillingar og öll notandagögn hennar glatast."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> árangurslausar tilraunir til að taka sjónvarpið úr lás. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> skipti í viðbót án árangurs verður sjónvarpið stillt á verksmiðjustillingar og þú glatar öllum notandagögnum."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Þú hefur gert <xliff:g id="NUMBER_0">%1$d</xliff:g> tilraunir til að opna símann. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður síminn stilltur á sjálfgefnar stillingar og öll notandagögn hans glatast."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> tilraunir til að opna spjaldtölvuna án árangurs. Hún verður nú stillt á sjálfgefnar stillingar."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að taka sjónvarpið úr lás. Sjónvarpið verður nú stillt aftur á verksmiðjustillingar."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> tilraunir til að opna símann án árangurs. Hann verður nú stilltur á sjálfgefnar stillingar."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður þú beðin(n) um að opna spjaldtölvuna með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%d</xliff:g> sekúndur."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. Ef þú teiknar rangt mynstur í <xliff:g id="NUMBER_1">%d</xliff:g> skipti í viðbót verður beðið um að þú notir tölvupóstreikning til að opna fyrir sjónvarpið.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%d</xliff:g> sekúndur."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%d</xliff:g> árangurslausar tilraunir í viðbót verður þú beðin(n) um að opna símann með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%d</xliff:g> sekúndur."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður þú beðin(n) um að opna spjaldtölvuna með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Ef þú teiknar rangt mynstur í <xliff:g id="NUMBER_1">%2$d</xliff:g> skipti í viðbót verður beðið um að þú notir tölvupóstreikning til að opna fyrir sjónvarpið.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verður þú beðin(n) um að opna símann með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjarlægja"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Hækka hljóðstyrk umfram ráðlagðan styrk?\n\nEf hlustað er á háum hljóðstyrk í langan tíma kann það að skaða heyrnina."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 617aac6..521eae2 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la Guida dell\'utente o contatta il servizio clienti."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La SIM è bloccata."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Sblocco SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con i tuoi dati di accesso Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Hai tracciato la sequenza di sblocco sbagliata per <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti ti verrà chiesto di sbloccare la TV utilizzando i tuoi dati di accesso di Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con i tuoi dati di accesso Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Hai erroneamente tentato di sbloccare il tablet <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti, il tablet verrà sottoposto a un ripristino dati di fabbrica e tutti i dati utente andranno persi."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Hai cercato di sbloccare la TV senza riuscirci per <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti verranno ripristinate le impostazioni predefinite di fabbrica della TV e tutti i dati utente verranno eliminati."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Hai erroneamente tentato di sbloccare il telefono <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti, il telefono verrà sottoposto a un ripristino dati di fabbrica e tutti i dati utente andranno persi."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Hai digitato la tua password <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con i tuoi dati di accesso Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Hai tracciato la sequenza di sblocco sbagliata per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi non riusciti ti verrà chiesto di sbloccare la TV utilizzando i tuoi dati di accesso di Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con i tuoi dati di accesso Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Hai erroneamente tentato di sbloccare il tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi non riusciti, il tablet verrà sottoposto a un ripristino dati di fabbrica e tutti i dati utente andranno persi."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Hai cercato di sbloccare la TV senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi non riusciti verranno ripristinate le impostazioni predefinite di fabbrica della TV e tutti i dati utente verranno eliminati."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Hai erroneamente tentato di sbloccare il telefono <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi non riusciti, il telefono verrà sottoposto a un ripristino dati di fabbrica e tutti i dati utente andranno persi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Hai erroneamente tentato di sbloccare il tablet <xliff:g id="NUMBER">%d</xliff:g> volte. Il tablet ora verrà sottoposto a un ripristino dati di fabbrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Hai cercato di sbloccare la TV senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Verranno ripristinate le impostazioni predefinite di fabbrica della TV."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Hai erroneamente tentato di sbloccare il telefono <xliff:g id="NUMBER">%d</xliff:g> volte. Il telefono ora verrà sottoposto a un ripristino dati di fabbrica."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"parola"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linea"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Test di fabbrica non riuscito"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"L\'azione FACTORY_TEST è supportata soltanto per i pacchetti installati in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nessun pacchetto trovato che fornisca l\'azione FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome utente o password non validi."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Hai dimenticato il nome utente o la password?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Controllo account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del tablet. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il tablet verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Hai cercato di sbloccare la TV senza riuscirci per <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti verranno ripristinate le impostazioni predefinite di fabbrica della TV e tutti i dati utente verranno eliminati."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del telefono. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il telefono verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Hai digitato la tua password <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di sblocco del tablet. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, il tablet verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Hai cercato di sbloccare la TV senza riuscirci per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi non riusciti verranno ripristinate le impostazioni predefinite di fabbrica della TV e tutti i dati utente verranno eliminati."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di sblocco del telefono. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, il telefono verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del tablet. Il tablet verrà sottoposto a un ripristino dei dati di fabbrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Hai cercato di sbloccare la TV senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Verranno ripristinate le impostazioni predefinite di fabbrica della TV."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del telefono. Il telefono verrà sottoposto a un ripristino dei dati di fabbrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Hai tracciato la sequenza di sblocco sbagliata per <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti ti verrà chiesto di sbloccare la TV utilizzando un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Hai tracciato la sequenza di sblocco sbagliata per <xliff:g id="NUMBER_0">%1$d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi non riusciti ti verrà chiesto di sbloccare la TV utilizzando un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Rimuovi"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Vuoi aumentare il volume oltre il livello consigliato?\n\nL\'ascolto ad alto volume per lunghi periodi di tempo potrebbe danneggiare l\'udito."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 719b404..4eb153a 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -684,15 +684,15 @@
     <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">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"‏הקלדת קוד PIN שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"‏שרטטת באופן שגוי את קו ביטול הנעילה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות פרטי הכניסה שלך ל-Google.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"‏שרטטת את קו ביטול הנעילה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים באופן שגוי. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלוויזיה באמצעות כניסה לחשבון Google שלך.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"‏שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. בעוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות פרטי הכניסה שלך ל-Google‏.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטאבלט. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטאבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ניסית לבטל את נעילת הטלוויזיה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים באופן שגוי. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטלוויזיה תאופס לנתוני היצרן וכתוצאה מכך כל נתוני המשתמש יאבדו."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטאבלט. הטאבלט יעבור כעת איפוס לברירת המחדל של היצרן."</string>
     <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>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"מילה"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"קישור"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"שורה"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"בדיקת היצרן נכשלה"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"‏הפעולה FACTORY_TEST נתמכת רק עבור חבילות שהותקנו ב-‎/system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"‏לא נמצאה חבילה המספקת את הפעולה FACTORY_TEST."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"שם משתמש או סיסמה לא חוקיים."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"‏שכחת את שם המשתמש או הסיסמה?\nבקר בכתובת "<b>"google.com/accounts/recovery"</b></string>
     <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">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטאבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ניסית לבטל את נעילת הטלוויזיה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים באופן שגוי. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטלוויזיה תאופס לנתוני היצרן וכתוצאה מכך כל נתוני המשתמש יאבדו."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטלפון יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</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_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">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון אימייל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"שרטטת את קו ביטול הנעילה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים באופן שגוי. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלוויזיה באמצעות חשבון אימייל.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון אימייל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 64da9fc..6f6d1b0 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -420,7 +420,7 @@
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"指紋ハードウェアを認証に使用することをアプリに許可します"</string>
     <string name="fingerprint_acquired_partial" msgid="735082772341716043">"指紋を一部しか検出できませんでした。もう一度お試しください。"</string>
     <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"指紋を処理できませんでした。もう一度お試しください。"</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"指紋センサーに汚れがあります。汚れを落としてもう一度お試しください。"</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"指紋認証センサーに汚れがあります。汚れを落としてもう一度お試しください。"</string>
     <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"指の動きが速すぎました。もう一度お試しください。"</string>
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"指の動きが遅すぎました。もう一度お試しください。"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -682,15 +682,15 @@
     <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">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"正しくないパスワードを<xliff:g id="NUMBER_0">%d</xliff:g>回入力しました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"正しくないPINを<xliff:g id="NUMBER_0">%d</xliff:g>回入力しました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にGoogleへのログインが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、テレビのロック解除にGoogleへのログインが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒以内にもう一度お試しください。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にGoogleへのログインが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"タブレットのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、タブレットは工場出荷状態にリセットされ、ユーザーのデータはすべて失われます。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"テレビのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、テレビは出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"端末のロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"タブレットのロック解除を<xliff:g id="NUMBER">%d</xliff:g>回失敗しました。タブレットを工場出荷状態にリセットします。"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"単語"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"リンク"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"行"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出荷時試験が失敗"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST操作は、/system/appにインストールされたパッケージのみが対象です。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST操作を行うパッケージは見つかりませんでした。"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ユーザー名またはパスワードが無効です。"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ユーザー名またはパスワードを忘れた場合は\n "<b>"google.com/accounts/recovery"</b>" にアクセスしてください。"</string>
     <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">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"パスワードの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"タブレットのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、タブレットは出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"テレビのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、テレビは出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"携帯端末のロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、端末は出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</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_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">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にメールアカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、テレビのロック解除にメールアカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒以内にもう一度お試しください。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にメールアカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 0bb03b0..94988ab 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"თქვენ არასწორად დაბეჭდეთ თქვენი პაროლი <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ დაგჭირდებათ თქვენი ტაბლეტის განბლოკვა Google-ში შესვლით.\n\n გთხოვთ, ხელახლა სცადოთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"თქვენ არასწორად შეიყვანეთ თქვენი განბლოკვის თარგი <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი მცდელობის შემდეგ, თქვენ მოგეთხოვებათ განბლოკოთ თქვენი Google შესვლის მონაცემების მეშვეობით. \n\n სცადეთ ხელახლა <xliff:g id="NUMBER_2">%d</xliff:g> წამი."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ დაგჭირდებათ თქვენი ტელეფონის განბლოკვა Google-ში შესვლით.\n\n გთხოვთ, ხელახლა სცადოთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"თქვენ არასწორად სცადეთ ტელევიზორის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდეც <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ტელევიზორი დაუბრუნდება ქარხნულ ნაგულისხმევ პარამეტრებს და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%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">"თქვენ <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"თქვენ <xliff:g id="NUMBER">%d</xliff:g>-ჯერ არასწორად სცადეთ ტაბლეტის განბლოკვა. ამიტომ ტაბლეტზე დადგება საწყისი, ქარხნული პარამეტრები."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"სიტყვა"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ბმული"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"სტრიქონი"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"წარმოების ტესტი ვერ განხორციელდა"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"აქტივობა FACTORY_TEST მხარდაჭერილია მხოლოდ იმ პაკეტებისთვის, რომლებიც მოთავსებულია /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"ვერ მოიძებნა პაკეტი, რომელიც უზრუნველყოფს ქარხნულ ტესტ ქმედებას."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"არასწორი სახელი, ან პაროლი."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"დაგავიწყდათ მომხმარებლის სახელი და პაროლი?\nეწვიეთ "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"მიმდინარეობს ანგარიშის შემოწმება…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად დაბეჭდეთ თქვენი პაროლი. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"თქვენ არასწორად სცადეთ ტელევიზორის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი მცდელობის შემდეგ, ტელევიზორი დაუბრუნდება ქარხნულ ნაგულისხმევ პარამეტრებს და მომხმარებლის ყველა მონაცემი დაკარგება."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტელეფონზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"თქვენ <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \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_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">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ მოგთხოვთ ტაბლეტის განბლოკვას ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"თქვენ არასწორად მოხაზეთ თქვენი განბლოკვის თარგი <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი მცდელობის შემდეგ, თქვენ მოგეთხოვებათ განბლოკოთ თქვენი ტელევიზორი ელ ანგარიშის მეშვეობით. \n\n სცადეთ ხელახლა <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ, დაგჭირდებათ თქვენი ტელეფონის განბლოკვა ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 4c957e1..8e45087 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> рет қате салдыңыз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Құпия сөзді <xliff:g id="NUMBER_0">%d</xliff:g> рет қате тердіңіз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундтан кейін қайталаңыз."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN кодын <xliff:g id="NUMBER_0">%d</xliff:g> рет қате тердіңіз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундтан кейін қайталаңыз."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Бекітпесін ашу өрнегін <xliff:g id="NUMBER_0">%d</xliff:g> рет қате салдыңыз. Тағы <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін сізден Google жүйесіне кіріп планшет бекітпесін ашу сұралады.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Бекітпесін ашу өрнегін <xliff:g id="NUMBER_0">%d</xliff:g> рет дұрыс емес салдыңыз. Тағы <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін сізден Google кіруді пайдаланып ТД бекітпесін ашу сұралады.\n\n Әрекетті <xliff:g id="NUMBER_2">%d</xliff:g> секундтан кейін қайталаңыз."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Бекітпесін ашу өрнегін <xliff:g id="NUMBER_0">%d</xliff:g> рет қате салдыңыз. Тағы <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін сізден Google жүйесіне кіріп телефон бекітпесін ашу сұралады.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Планшеттің бекітпесін ашуға <xliff:g id="NUMBER_0">%d</xliff:g> рет қате әрекеттендіңіз. <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін, телефон зауыттың бастапқы параметрлеріне қайта реттеледі және пайдаланушы деректері жоғалады."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ТД бекітпесін <xliff:g id="NUMBER_0">%d</xliff:g> рет дұрыс емес ашу әрекетін жасадыңыз. Тағы <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін ТД зауыттық әдепкі параметрлері қалпына келтіріледі және бүкіл пайдаланушы деректері жоғалады."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Телефонның бекітпесін ашуға <xliff:g id="NUMBER_0">%d</xliff:g> рет қате әрекеттендіңіз. <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Планшетті ашуға <xliff:g id="NUMBER">%d</xliff:g> рет қате әрекеттендіңіз. Планшет зауыттың бастапқы параметрлеріне қайта реттеледі."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"сөз"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"сілтеме"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"сызық"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Зауыт тесті орындалмады."</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"ЗАУЫТ_TEСТІ әрекетінің қолдауы жүйеде/қолданбада орнатылған жинақтар үшін ғана ұсынылған."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"ЗАУЫТ_TEСТІ әрекетін жабдықтайтын жинақ табылмады."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Пайдаланушы атауы немесе кілтсөз жарамсыз."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Пайдаланушы атауын немесе кілтсөзді ұмытып қалдыңыз ба?\n"<b>"google.com/accounts/recovery"</b>" веб-сайтына кіріңіз."</string>
     <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">%d</xliff:g> рет қате тердіңіз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундтан кейін қайталаңыз."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Құпия сөзді <xliff:g id="NUMBER_0">%d</xliff:g> рет қате тердіңіз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундтан кейін қайталаңыз."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Құлыпты ашу өрнегін <xliff:g id="NUMBER_0">%d</xliff:g> рет қате салдыңыз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Планшетті ашуға <xliff:g id="NUMBER_0">%d</xliff:g> рет қате әрекеттендіңіз. <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін телефоныңыз бастапқы зауыттық параметрлеріне қайта реттеледі және барлық пайдаланушы деректері жойылады."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ТД бекітпесін <xliff:g id="NUMBER_0">%d</xliff:g> рет дұрыс емес ашу әрекетін жасадыңыз. Тағы <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін ТД зауыттық әдепкі параметрлері қалпына келтіріледі және бүкіл пайдаланушы деректері жоғалады."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Телефонды ашуға <xliff:g id="NUMBER_0">%d</xliff:g> рет қате әрекеттендіңіз. <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін телефоныңыз бастапқы зауыттық параметрлеріне қайта реттеледі және барлық пайдаланушы деректері жойылады."</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_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">%d</xliff:g> рет қате сыздыңыз. After <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін планшетіңізді есептік жазба арқылы ашу өтінішін аласыз.\n\n  <xliff:g id="NUMBER_2">%d</xliff:g> секундтан кейін қайта әрекеттеніңіз."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Бекітпесін ашу өрнегін <xliff:g id="NUMBER_0">%d</xliff:g> рет қате салдыңыз. Тағы <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін сізден электрондық пошта есептік жазбасын пайдаланып ТД бекітпесін ашу сұралады.\n\n Әрекетті <xliff:g id="NUMBER_2">%d</xliff:g> секундтан кейін қайталаңыз."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Бекітпені ашу кескінін <xliff:g id="NUMBER_0">%d</xliff:g> рет қате сыздыңыз. <xliff:g id="NUMBER_1">%d</xliff:g> сәтсіз әрекеттен кейін телефоныңызды есептік жазба арқылы ашу өтінішін аласыз. \n\n <xliff:g id="NUMBER_2">%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> рет қате сыздыңыз. After <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>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index ced8c12..69fe257 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"មើល​មគ្គុទ្ទេសក៍​អ្នក​ប្រើ ឬ​ទាក់ទង​សេវា​អតិថិជន។"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"ស៊ីមកាត​​ជាប់​សោ។"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"កំពុង​ដោះ​សោ​ស៊ីមកាត..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ \n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​របស់​អ្នក​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ \n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"អ្នក​បាន​បញ្ចូល​កូដ​ PIN មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ \n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​របស់​អ្នក ដោយ​ប្រើ​ការ​ចូល​ក្នុង​គណនី Google របស់​អ្នក។\n\n សូម​ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"អ្នកបានគូសលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់ពីការព្យាយាមបរាជ័យ <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត អ្នកនឹងត្រូវបានសួរឲ្យដោះសោទូរទស្សន៍របស់អ្នកដោយប្រើការចូលគណនី Google។\n\n ព្យាយាមម្តងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ <xliff:g id="NUMBER_1">%d</xliff:g> ដង​ទៀត អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​ការ​ចូល​ Google ។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​ <xliff:g id="NUMBER_1">%d</xliff:g> ដង​ទៀត កុំព្យូទ័រ​បន្ទះ​នឹង​ត្រូវ​បាន​កំណត់​ដូច​ចេញ​ពី​រោងចក្រ​ឡើងវិញ ហើយ​ទិន្នន័យ​អ្នក​ប្រើ​ទាំងអស់​នឹង​បាត់បង់។"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"អ្នកបានព្យាយាមដោះសោទូរទស្សន៍របស់អ្នកមិនត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់ពីការព្យាយាមបរាជ័យ <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត ទូរទស្សន៍របស់អ្នកនឹងត្រូវបានកំណត់ឡើងវិញទាំងស្រុងតាមលំនាំដើម ហើយទិន្នន័យអ្នកប្រើទាំងអស់នឹងត្រូវបាត់បង់។"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"អ្នក​បាន​ព្យាយាម​​ដោះ​សោ​​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដង។ ឥឡូវ​កុំព្យូទ័រ​បន្ទះ​នឹង​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោង​ចក្រ។"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ពាក្យ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"តំណ"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"បន្ទាត់"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"បាន​បរាជ័យ​ក្នុង​ការ​សាកល្បង​រោងចក្រ"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវ​បាន​គាំទ្រ​សម្រាប់​តែ​កញ្ចប់​បាន​ដំឡើង​ក្នុង /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"រក​មិន​ឃើញ​កញ្ចប់​ដែល​ផ្ដល់​សកម្មភាព FACTORY_TEST ។"</string>
@@ -1287,18 +1285,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះ​អ្នកប្រើ ឬ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេច​ឈ្មោះ​អ្នកប្រើ ឬ​ពាក្យ​សម្ងាត់​របស់​អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
     <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">%d</xliff:g> ដង។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"អ្នក​បាន​​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង កុំព្យូទ័រ​បន្ទះ​​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ ហើយ​ទិន្នន័យ​អ្នកប្រើ​នឹង​បាត់បង់។"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"អ្នកបានព្យាយាមដោះសោទូរទស្សន៍របស់អ្នកមិនត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់ពីការព្យាយាមបរាជ័យ <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត ទូរទស្សន៍របស់អ្នកនឹងត្រូវបានកំណត់ឡើងវិញទាំងស្រុងតាមលំនាំដើម ហើយទិន្នន័យអ្នកប្រើទាំងអស់នឹងត្រូវបាត់បង់។"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង ទូរស័ព្ទ​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ ហើយ​ទិន្នន័យ​អ្នកប្រើ​នឹង​បាត់បង់។"</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_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">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម <xliff:g id="NUMBER_1">%d</xliff:g> ដង​មិន​ជោគជ័យ អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"អ្នកបានគូសលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់ពីការព្យាយាមបរាជ័យ <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត អ្នកនឹងត្រូវបានសួរឲ្យដោះសោទូរទស្សន៍របស់អ្នកដោយប្រើគណនីអ៊ីម៉ែល។\n\n ព្យាយាមម្តងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើនជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index dbaa45f..f3ff668 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ಬಳಕೆದಾರರ ಮಾರ್ಗಸೂಚಿಯನ್ನು ನೋಡಿ ಅಥವಾ ಗ್ರಾಹಕರ ಸಹಾಯ ಕೇಂದ್ರಕ್ಕೆ ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"ಸಿಮ್‌ ಕಾರ್ಡ್ ಲಾಕ್ ಆಗಿದೆ."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"ಸಿಮ್‌ ಕಾರ್ಡ್ ಅನ್‌ಲಾಕ್  ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ನಮೂನೆಯನ್ನುನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ನಿಮ್ಮ ಪಾಸ್‍‍ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ನಿಮ್ಮ ಅನ್‌ಲಾಕ್‌ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್‌ ಇನ್‌ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"<xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ನಿಮ್ಮ ಅನ್‌ಲಾಕ್ ನಮೂನೆಯನ್ನು ನೀವು ತಪ್ಪಾಗಿ ಎಳೆದಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನೀವು ಟಿವಿಯನ್ನು Google ಗೆ ಸೈನ್ ಇನ್ ಮಾಡುವ ಮೂಲಕ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಕೇಳಲಾಗುತ್ತದೆ.\n\n<xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳ ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ನಿಮ್ಮ ಅನ್‌ಲಾಕ್‌ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್‌ ಇನ್‌ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಫೋನ್‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ಟಿವಿಯನ್ನು ತಪ್ಪಾಗಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟಿವಿಯನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುವುದು ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%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">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ಪದ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ಲಿಂಕ್"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ಸಾಲು"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ಫ್ಯಾಕ್ಟರಿ ಪರೀಕ್ಷೆ ವಿಫಲವಾಗಿದೆ"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ಕ್ರಿಯೆಯು /system/app ನಲ್ಲಿ ಸ್ಥಾಪಿಸಲಾಗಿರುವ ಪ್ಯಾಕೇಜ್‌ಗಳಿಗೆ ಮಾತ್ರ ಬೆಂಬಲಿಸುತ್ತದೆ."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST ಕ್ರಿಯೆಯನ್ನು ಒದಗಿಸುವಂತಹ ಯಾವುದೇ ಪ್ಯಾಕೇಜ್ ಕಂಡುಬಂದಿಲ್ಲ."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ಅಮಾನ್ಯ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ನಿಮ್ಮ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್‍ವರ್ಡ್ ಮರೆತಿರುವಿರಾ?\n"<b>"google.com/accounts/recovery"</b>" ಗೆ ಭೇಟಿ ನೀಡಿ."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"ಖಾತೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ನಿಮ್ಮ ಪಾಸ್‍‍ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ಟಿವಿಯನ್ನು ತಪ್ಪಾಗಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟಿವಿಯನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುವುದು ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g>  ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <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_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">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಡ್ರಾ ಮಾಡಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡುವಂತೆ ನಿಮ್ಮಲ್ಲಿ ಕೇಳಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"<xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ನಿಮ್ಮ ಅನ್‌ಲಾಕ್ ನಮೂನೆಯನ್ನು ನೀವು ತಪ್ಪಾಗಿ ಎಳೆದಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನೀವು ಟಿವಿಯನ್ನು ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆ ಬಳಸಿಕೊಂಡು ಅನ್‌ಲಾಕ್ ಮಾಡುವಂತೆ ಕೇಳಲಾಗುತ್ತದೆ.\n\n<xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳ ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಡ್ರಾ ಮಾಡಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡುವಂತೆ ನಿಮ್ಮಲ್ಲಿ ಕೇಳಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 0018a46..fbc6ac2 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g>회 잘못 그렸습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 Google 로그인을 통해 태블릿을 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 잘못 입력하면 Google 로그인을 통해 TV를 잠금 해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 Google 로그인을 통해 휴대전화를 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"태블릿을 잠금 해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>번 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>번 더 실패하면 태블릿이 초기화되고 사용자 데이터가 모두 손실됩니다."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"TV 잠금 해제 시도를 <xliff:g id="NUMBER_0">%d</xliff:g>회 실패했습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 TV가 초기화되고 모든 사용자 데이터가 삭제됩니다."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"휴대전화를 잠금 해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>번 잘못되었습니다. <xliff:g id="NUMBER_1">%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 로그인을 통해 TV를 잠금 해제해야 합니다.\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">"TV 잠금 해제 시도를 <xliff:g id="NUMBER_0">%1$d</xliff:g>회 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>회 더 실패하면 TV가 초기화되고 모든 사용자 데이터가 삭제됩니다."</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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"태블릿을 잠금 해제하려는 시도가 <xliff:g id="NUMBER">%d</xliff:g>번 잘못되었습니다. 태블릿이 초기화됩니다."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"TV 잠금 해제 시도를 <xliff:g id="NUMBER">%d</xliff:g>회 실패했으므로 지금 TV가 초기화됩니다."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"휴대전화를 잠금 해제하려는 시도가 <xliff:g id="NUMBER">%d</xliff:g>번 잘못되었습니다. 휴대전화가 초기화됩니다."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"단어"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"링크"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"행"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="AMPM">%P</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>시"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="AMPM">%p</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>시"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"출고 테스트 불합격"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST 작업은 /system/app 디렉토리에 설치된 패키지에 대해서만 지원됩니다."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST 작업을 제공하는 패키지가 없습니다."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"사용자 이름 또는 비밀번호가 잘못되었습니다."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"사용자 이름이나 비밀번호를 잊어버렸습니까?\n"<b>"google.com/accounts/recovery"</b>" 페이지를 방문하세요."</string>
     <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">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"태블릿을 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 태블릿이 초기화되고 사용자 데이터가 모두 사라집니다."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"TV 잠금 해제 시도를 <xliff:g id="NUMBER_0">%d</xliff:g>회 실패했습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 TV가 초기화되고 모든 사용자 데이터가 삭제됩니다."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"휴대전화를 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 휴대전화가 초기화되고 사용자 데이터가 모두 사라집니다."</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_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">"TV 잠금 해제 시도를 <xliff:g id="NUMBER_0">%1$d</xliff:g>회 실패했습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>회 더 실패하면 TV가 초기화되고 모든 사용자 데이터가 삭제됩니다."</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">"TV 잠금 해제 시도를 <xliff:g id="NUMBER">%d</xliff:g>회 실패했으므로 지금 TV가 초기화됩니다."</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">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. 앞으로 <xliff:g id="NUMBER_1">%d</xliff:g>회 더 잘못 입력하면 이메일 계정을 사용해서 TV의 잠금을 해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%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>회 더 잘못 입력하면 이메일 계정을 사용해서 TV의 잠금을 해제해야 합니다.\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>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 04e6539..5263dd8 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -683,15 +683,15 @@
     <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">%d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN-кодуңузду <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> жолу туура эмес тартсаңыз, сыналгыңыздын кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Сиз планшетиңизди бөгөттөн чыгарууга <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> аракеттен кийин, планшет баштапкы абалына келтирилет жана бардык маалыматтар жок кылынат."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> жолу туура эмес тартсаңыз, сыналгыңыз баштапкы абалга келтирилип, колдонуучунун бардык дайындары жок болот."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Сиз телефонуңузду бөгөттөн чыгарууга <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Дагы <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Сиз планшетти бөгөттөн чыгарууга <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Планшет баштапкы абалына келтирилет."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Сыналгыңыздын кулпусун ачууда <xliff:g id="NUMBER">%d</xliff:g>_0 жолу туура эмес аракет кылдыңыз. Сыналгыңыз баштапкы абалга келтирилет."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Сиз телефонду бөгөттөн чыгарууга <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Телефон баштапкы абалына келтирилет."</string>
@@ -743,8 +743,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"сөз"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"шилтеме"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"сап"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Заводдук сынак ишке ашкан жок"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST аракети /system/app ичинде орнотулган топтомдор үчүн гана колдоого алынат."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST аракетин камсыздаган эч бир топтом табылган жок."</string>
@@ -1286,18 +1284,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Колдонуучу атыңыз же сырсөзүңүз туура эмес."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Колдонуучу атыңызды же сырсөзүңүздү унутуп калдыңызбы?\n"<b>"google.com/accounts/recovery"</b>" дарегине кайрылыңыз."</string>
     <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">%d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин кайталаңыз."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Сиз сырсөзүңүздү <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин кайталаңыз."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Сиз бөгөттөн чыгаруу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес көрсөттүңүз. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> секундадан кийин кайталаңыз."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Сиз планшетиңизди <xliff:g id="NUMBER_0">%d</xliff:g> жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> ийгиликсиз аракеттен кийин, планшет баштапкы абалына кайтарылат жана бардык берилиштериңиз жок кылынат."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> жолу туура эмес тартсаңыз, сыналгыңыз баштапкы абалга келтирилип, колдонуучунун бардык дайындары жок болот."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Сиз телефонуңузду <xliff:g id="NUMBER_0">%d</xliff:g> жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> ийгиликсиз аракеттен кийин, телефон баштапкы абалына кайтарылат жана бардык берилиштериңиз жок кылынат."</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_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>_0 жолу туура эмес аракет кылдыңыз. Сыналгыңыз баштапкы абалга келтирилет."</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">%d</xliff:g> жолу туура эмес көрсөттүңүз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> ийгиликсиз аракеттен кийин, планшетиңизди эмейл эсебиңиз аркылуу бөгөттөн чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундадан кийин кайра аракеттениңиз."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> жолу туура эмес тартсаңыз, сыналгыңыздын кулпусун электрондук каттоо эсебиңизге кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Сиз бөгөттөн чыгаруу үлгүсүн <xliff:g id="NUMBER_0">%d</xliff:g> жолу туура эмес көрсөттүңүз. Дагы <xliff:g id="NUMBER_1">%d</xliff:g> ийгиликсиз аракеттен кийин, телефонуңузду эмейл эсебиңиз аркылуу бөгөттөн чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 2f0072a..805982a 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ເບິ່ງຄູ່ມືຜູ່ໃຊ້ ຫຼືຕິດຕໍ່ສູນບໍລິການລູກຄ້າ."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card ຖືກລັອກ."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"ກຳລັງປົດລັອກຊິມກາດ..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"ທ່ານແຕ້ມຮູບແບບປົດລັອກບໍ່ຖືກ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ທ່ານພິມລະຫັດຜ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nໃຫ້ລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ທ່ານພິມລະຫັດ PIN ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບຂອງ Google.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ທ່ານ​ແຕ້ມ​​ແບບຮູບ​ປົດ​ລັອກຂອງ​ທ່ານ​ບໍ່​ຖືກ​ຕ້ອງ <xliff:g id="NUMBER_0">%d</xliff:g> ຄັ້ງ​ແລ້ວ. ຫຼັງ​ຈາກລອງ​ບໍ່​ສຳ​ເລັດ​ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ຄັ້ງ, ທ່ານ​ຈະ​ຖືກບອກ​ໃຫ້​ປົດ​ລັອກໂທລະພາບຂອງ​ທ່ານ​ດ້ວຍ​ການ​ໃຊ້​ການ​ລົງ​ຊື່​ເຂົ້າ​ໃຊ້​ Google ຂອງ​ທ່ານ.\n\n ລອງ​ໃໝ່​ອີກ​ໃນ <xliff:g id="NUMBER_2">%d</xliff:g> ວິ​ນາ​ທີ."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບ Google.\n\n ລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ທ່ານພະຍາຍາມປັດລັອກແທັບເລັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ແທັບເລັດຈະຖືກຣີເຊັດໃຫ້ເປັນແບບທີ່ມາຈາກໂຮງງານ ແລະຂໍ້ມູນທັງໝົດຈະຖືກຫາຍໄປ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ທ່ານ​ພະ​ຍາ​ຍາມ​ປົດ​ລັອກໂທລະພາບບໍ່​ຖືກ​ຕ້ອງ <xliff:g id="NUMBER_0">%d</xliff:g> ຄັ້ງ​ແລ້ວ. ຫຼັງ​ຈາກ​ລອງ​ບໍ່​ສຳ​ເລັດ​ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ຄັ້ງ, ໂທລະພາບຈະ​ຖືກ​ຕັ້ງ​ຄ່າ​ເປັນ​ຄ່າ​ມາດ​ຕະ​ຖານ​ໂຮງ​ງານ​ຄືນ ແລະ​ຂໍ້​ມູນ​ຜູ້​ໃຊ້​ທັງ​ໝົດ​ຈະ​ເສຍ​ໄປ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບເປັນຈຳນວນ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກການພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ທ່ານພະຍາຍາມປົດລັອກແທັບເລັດຜິດ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອແລ້ວ. ຕອນນີ້ແທັບເລັດຈະຖືກຣີເຊັດເປັນຄ່າຈາກໂຮງງານ."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ຄຳສັບ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ລິ້ງ"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ເສັ້ນ"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ການທົດສອບຈາກໂຮງງານລົ້ມເຫລວ"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"ການເຮັດ FACTORY_TEST ຮອງຮັບສະເພາະແພັກເກດທີ່ຖືກຕິດຕັ້ງໃນ /system/app ເທົ່ານັ້ນ."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"ບໍ່ພົບແພັກເກດທີ່ມີການເຮັດວຽກ FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ຊື່ຜູ່ໃຊ້ ຫຼືລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ລືມຊື່ຜູ່ໃຊ້ ຫຼືລະຫັດຜ່ານຂອງທ່ານບໍ່?\nໄປທີ່ "<b>"google.com/accounts/recovery"</b>"."</string>
     <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">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ທ່ານພິມລະຫັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ແທັບເລັດຂອງທ່ານຈະຖືກຕັ້ງ ໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານຄືນໃໝ່ ແລະຂໍ້ມູນຜູ່ໃຊ້ທັງໝົດຈະສູນຫາຍໄປ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ທ່ານ​ພະ​ຍາ​ຍາມ​ປົດ​ລັອກໂທລະພາບບໍ່​ຖືກ​ຕ້ອງ <xliff:g id="NUMBER_0">%d</xliff:g> ຄັ້ງແລ້ວ. ຫຼັງ​ຈາກ​ລອງ​ບໍ່​ສຳ​ເລັດ​ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ຄັ້ງ, ໂທລະພາບຈະ​ຖືກ​ຕັ້ງ​ຄ່າ​ເປັນ​ຄ່າ​ມາດ​ຕະ​ຖານ​ໂຮງ​ງານ​ຄືນ ແລະ​ຂໍ້​ມູນ​ຜູ້​ໃຊ້​ທັງ​ໝົດ​ຈະ​ເສຍ​ໄປ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ໂທລະສັບຂອງທ່ານຈະຖືກຕັ້ງ ໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານຄືນໃໝ່ ແລະຂໍ້ມູນຜູ່ໃຊ້ທັງໝົດຈະສູນຫາຍໄປ."</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_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">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ທ່ານ​ແຕ້ມ​​ແບບຮູບ​ປົດ​ລັອກຂອງ​ທ່ານ​ບໍ່​ຖືກ​ຕ້ອງ <xliff:g id="NUMBER_0">%d</xliff:g> ຄັ້ງ​ແລ້ວ. ຫຼັງ​ຈາກລອງ​ບໍ່​ສຳ​ເລັດ​ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ຄັ້ງ, ທ່ານ​ຈະ​ຖືກບອກ​ໃຫ້​ປົດ​ລັອກໂທລະພາບຂອງ​ທ່ານ​ດ້ວຍ​ການ​ໃຊ້​ບັນ​ຊີ​ອີ​ເມ​ວ.\n\n ລອງ​ອີກ​ໃນ <xliff:g id="NUMBER_2">%d</xliff:g> ວິ​ນາ​ທີ."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍບັນຊີອີເມວ.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 17b38b1..3d3e333 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -684,15 +684,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Žr. naudotojo vadovą arba susisiekite su klientų priežiūros tarnyba."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kortelė užrakinta."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Atrakinama SD kortelė..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Neteisingai apibrėžėte atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodą neteisingai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%d</xliff:g> nesėkming. bandym. būsite paprašyti atrakinti TV prisijungdami prie „Google“.\n\n Bandykite dar kartą už <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"<xliff:g id="NUMBER_0">%d</xliff:g> kart. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Netinkamai bandėte atrakinti TV <xliff:g id="NUMBER_0">%d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%d</xliff:g> nesėkming. bandym. bus atkurti gamykliniai TV nustatymai, o visi naudotojo duomenys bus prarasti."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"<xliff:g id="NUMBER_0">%d</xliff:g> kart. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Neteisingai apibrėžėte atrakinimo modelį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodą neteisingai įvedėte <xliff:g id="NUMBER_0">%1$d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkming. bandym. būsite paprašyti atrakinti TV prisijungdami prie „Google“.\n\n Bandykite dar kartą už <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Netinkamai bandėte atrakinti TV <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkming. bandym. bus atkurti gamykliniai TV nustatymai, o visi naudotojo duomenys bus prarasti."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"<xliff:g id="NUMBER">%d</xliff:g> kart. bandėte netinkamai atrakinti planšetinį kompiuterį. Planšetinis kompiuteris bus iš naujo nustatytas į numatytuosius gamyklos nustatymus."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Netinkamai bandėte atrakinti TV <xliff:g id="NUMBER">%d</xliff:g> k. Dabar bus atkurti gamykliniai TV nustatymai."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"<xliff:g id="NUMBER">%d</xliff:g> kart. bandėte netinkamai atrakinti telefoną. Telefonas bus iš naujo nustatytas į numatytuosius gamyklos nustatymus."</string>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"žodis"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"nuoroda"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"eilutė"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Gamyklos bandymas nepavyko"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Veiksmas FACTORY_TEST palaikomas tik paketuose, įdiegtuose /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nerasta paketo, kuris teiktų FACTORY_TEST veiksmą."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Netinkamas naudotojo vardas ar slaptažodis."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Pamiršote naudotojo vardą ar slaptažodį?\nApsilankykite šiuo adresu: "<b>"google.com/accounts/recovery"</b></string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Tikrinama paskyra…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodą netinkamai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Netinkamai bandėte atrakinti TV <xliff:g id="NUMBER_0">%d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%d</xliff:g> nesėkming. bandym. bus atkurti gamykliniai TV nustatymai, o visi naudotojo duomenys bus prarasti."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodą netinkamai įvedėte <xliff:g id="NUMBER_0">%1$d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%1$d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Netinkamai bandėte atrakinti TV <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkming. bandym. bus atkurti gamykliniai TV nustatymai, o visi naudotojo duomenys bus prarasti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%1$d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Netinkamai bandėte atrakinti TV <xliff:g id="NUMBER">%d</xliff:g> k. Dabar bus atkurti gamykliniai TV nustatymai."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%d</xliff:g> nesėkming. bandym. būsite paprašyti atrakinti TV naudodami el. pašto paskyrą.\n\n Bandykite dar kartą už <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Dar po <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkming. bandym. būsite paprašyti atrakinti TV naudodami el. pašto paskyrą.\n\n Bandykite dar kartą už <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%1$d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Pašalinti"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Padidinti garsą daugiau nei rekomenduojamas lygis?\n\nIlgai klausydami dideliu garsu galite pažeisti klausą."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 091cd61..f233737 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -683,15 +683,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Skatiet lietotāja rokasgrāmatu vai sazinieties ar klientu apkalpošanas dienestu."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karte ir bloķēta."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Notiek SIM kartes atbloķēšana..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jūs esat ievadījis nepareizu paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jūs esat ievadījis nepareizu PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot pierakstīšanos Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Grafiskā atslēga tika nepareizi norādīta <xliff:g id="NUMBER_0">%d</xliff:g> reizi(-es). Ja nepareizi norādīsiet to vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizi(-es), televizors būs jāatbloķē, pierakstoties Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundes(-ēm)."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot pierakstīšanos Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi, un lietotāja dati tiks zaudēti."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Jūs <xliff:g id="NUMBER_0">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt televizoru. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) televizorā tiks veikta rūpnīcas datu atiestatīšana un visi lietotāja dati tiks zaudēti."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi, un lietotāja dati tiks zaudēti."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jūs esat ievadījis nepareizu paroli <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jūs esat ievadījis nepareizu PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot pierakstīšanos Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Grafiskā atslēga tika nepareizi norādīta <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es). Ja nepareizi norādīsiet to vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> reizi(-es), televizors būs jāatbloķē, pierakstoties Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot pierakstīšanos Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi, un lietotāja dati tiks zaudēti."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt televizoru. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) televizorā tiks veikta rūpnīcas datu atiestatīšana un visi lietotāja dati tiks zaudēti."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi, un lietotāja dati tiks zaudēti."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt televizoru. Tagad tiks veikta rūpnīcas datu atiestatīšana."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
@@ -743,8 +743,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"vārds"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"saite"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"rindiņa"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> (<xliff:g id="AMPM">%P</xliff:g>)"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> (<xliff:g id="AMPM">%p</xliff:g>)"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Rūpnīcas pārbaude neizdevās"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Darbība FACTORY_TEST tiek atbalstīta tikai pakotnēm, kas ir instalētas šeit: /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Netika atrasts neviena pakotne, kas nodrošina darbību FACTORY_TEST."</string>
@@ -1293,18 +1291,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nederīgs lietotājvārds vai parole."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vai aizmirsāt lietotājvārdu vai paroli?\nApmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Notiek konta pārbaude…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jūs nepareizi ievadījāt PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jūs nepareizi ievadījāt paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Jūs <xliff:g id="NUMBER_0">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt televizoru. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) televizorā tiks veikta rūpnīcas datu atiestatīšana un visi lietotāja dati tiks zaudēti."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jūs nepareizi ievadījāt PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jūs nepareizi ievadījāt paroli <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundēm."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīgiem mēģinājumiem planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt televizoru. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) televizorā tiks veikta rūpnīcas datu atiestatīšana un visi lietotāja dati tiks zaudēti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīgiem mēģinājumiem tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt televizoru. Tagad tiks veikta rūpnīcas datu atiestatīšana."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Grafiskā atslēga tika nepareizi norādīta <xliff:g id="NUMBER_0">%d</xliff:g> reizi(-es). Ja nepareizi norādīsiet to vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizi(-es), televizors būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundes(-ēm)."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundēm."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Grafiskā atslēga tika nepareizi norādīta <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es). Ja nepareizi norādīsiet to vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> reizi(-es), televizors būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%1$d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundēm."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">"  — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Noņemt"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Vai palielināt skaļumu virs ieteicamā līmeņa?\n\nIlgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 973fd2e..62ba912 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Погледнете го Упатството за корисници или контактирајте со Грижа за корисници."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"СИМ картичката е заклучена."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"СИМ картичката се отклучува..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Погрешно сте ја употребиле вашата шема за отклучување <xliff:g id="NUMBER_0">%d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Погрешно сте ја впишале вашата лозинка <xliff:g id="NUMBER_0">%d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Погрешно сте го впишале вашиот ПИН <xliff:g id="NUMBER_0">%d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Погрешно ја употребивте шемата за отклучување <xliff:g id="NUMBER_0">%d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, ќе побараме да го отклучите таблетот со пријавата за Google.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Неправилно ја исцртавте шемата за отклучување <xliff:g id="NUMBER_0">%d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, ќе биде побарано да го отклучите вашиот телевизор со пријавување на Google.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Погрешно ја употребивте шемата за отклучување <xliff:g id="NUMBER_0">%d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, ќе побараме да го отклучите телефонот со пријавата за Google.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Имавте <xliff:g id="NUMBER_0">%d</xliff:g> неуспешни обиди да го отклучите таблетот. Ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди и таблетот ќе се ресетира на фабричките подесувања и сите податоци на корисникот ќе се изгубат."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Неправилно се обидовте да го отклучите вашиот телевизор <xliff:g id="NUMBER_0">%d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, телевизорот ќе се ресетира на стандардните фабрички вредности и сите податоци на корисникот ќе бидат изгубени."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Имавте <xliff:g id="NUMBER_0">%d</xliff:g> неуспешни обиди да го отклучите телефонот. Ви преостануваат уште <xliff:g id="NUMBER_1">%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">"Погрешно сте го впишале вашиот ПИН <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Имавте <xliff:g id="NUMBER">%d</xliff:g> неуспешни обиди да го отклучите таблетот. Сега таблетот ќе се ресетира на фабричките подесувања."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"збор"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"врска"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"линија"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Фабричкото тестирање не успеа"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Дејството на FACTORY_TEST е поддржано само за пакети инсталирани во /систем /апликација."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Не е пронајден пакет што овозможува дејство на FACTORY_TEST."</string>
@@ -1287,18 +1285,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Неважечко корисничко име или лозинка."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Го заборави своето корисничко име или лозинката?\nПосети"<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Сметката се проверува..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Погрешно сте го впишале вашиот ПИН <xliff:g id="NUMBER_0">%d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Погрешно сте ја впишале вашата лозинка <xliff:g id="NUMBER_0">%d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Погрешно сте ја употребиле вашата шема за отклучување <xliff:g id="NUMBER_0">%d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Погрешно сте се обиделе да го отклучите телефонот <xliff:g id="NUMBER_0">%d</xliff:g> пати. По <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, телефонот ќе се ресетира на фабрички стандардни вредности и сите податоци за корисникот ќе се изгубат."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Неправилно се обидовте да го отклучите вашиот телевизор <xliff:g id="NUMBER_0">%d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, телевизорот ќе се ресетира на стандардните фабрички вредности и сите податоци на корисникот ќе бидат изгубени."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Погрешно сте се обиделе да го отклучите телефонот <xliff:g id="NUMBER_0">%d</xliff:g> пати. По <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, телефонот ќе се ресетира на фабрички стандардни вредности и сите податоци за корисникот ќе се изгубат."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Погрешно сте го впишале вашиот ПИН <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_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">%d</xliff:g> пати. По <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, ќе побараат од вас да го отклучите таблетот со користење сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Неправилно ја исцртавте шемата за отклучување <xliff:g id="NUMBER_0">%d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, ќе биде побарано да го отклучите вашиот телевизор со помош на вашата сметка за е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Погрешно сте ја употребиле вашата шема на отклучување <xliff:g id="NUMBER_0">%d</xliff:g> пати. По <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни обиди, ќе побараат од вас да го отклучите телефонот со користење сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 61afb46..925688d 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ഉപയോക്തൃ ഗൈഡ് കാണുകയോ കസ്‌റ്റമർ കെയറുമായി ബന്ധപ്പെടുകയോ ചെയ്യുക."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"സിം കാർഡ് ലോക്കുചെയ്‌തു."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"സിം കാർഡ് അൺലോക്കുചെയ്യുന്നു…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"നിങ്ങളുടെ പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"നിങ്ങളുടെ പാസ്‌വേഡ് <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ടൈപ്പുചെയ്‌തു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"നിങ്ങളുടെ പിൻ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ടൈപ്പുചെയ്‌തു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"നിങ്ങളുടെ അൺലോക്കുചെയ്യൽ പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> തെറ്റായ ശ്രമങ്ങൾക്കുശേഷം, Google സൈൻ ഇൻ ചെയ്യൽ ഉപയോഗിച്ച് നിങ്ങളുടെ ടാബ്‌ലെറ്റ് അൺലോക്കുചെയ്യുന്നതിന് ആവശ്യപ്പടും.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"നിങ്ങൾ അൺലോക്കുചെയ്യൽ പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g>-ൽ കൂടുതൽ പരാജയപ്പെട്ട ശ്രമങ്ങൾക്കുശേഷം, Google സൈൻ ഇൻ ചെയ്യൽ ഉപയോഗിച്ച് നിങ്ങളുടെ ടിവി അൺലോക്കുചെയ്യുന്നതിന് ആവശ്യപ്പടും. \n\n <xliff:g id="NUMBER_2">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"നിങ്ങൾ അൺലോക്കുചെയ്യൽ പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> തെറ്റായ ശ്രമങ്ങൾക്കുശേഷം, Google സൈൻ ഇൻ ചെയ്യൽ ഉപയോഗിച്ച് നിങ്ങളുടെ ഫോൺ അൺലോക്കുചെയ്യുന്നതിന് ആവശ്യപ്പടും. \n\n <xliff:g id="NUMBER_2">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"നിങ്ങൾ ഫോൺ അൺലോക്കുചെയ്യാൻ തവണ <xliff:g id="NUMBER_0">%d</xliff:g> തെറ്റായി ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി വിജയിച്ചില്ലെങ്കിൽ, ടാബ്‌ലെറ്റ് ഫാക്‌ടറി സ്ഥിരമായതിലേക്ക് പുനഃസജ്ജികരിക്കുകയും ഉപയോക്തൃ ഡാറ്റയെല്ലാം നഷ്‌ടപ്പെടുകയും ചെയ്യും."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ടിവി അൺലോക്കുചെയ്യൽ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ചെയ്‌തു. <xliff:g id="NUMBER_1">%d</xliff:g>-ൽ കൂടുതൽ പരാജയപ്പെട്ട ശ്രമങ്ങൾക്കുശേഷം, ടിവി ഫാക്‌ടറി സ്ഥിരതയിലേക്ക് പുനഃസജ്ജീകരിക്കുകയും എല്ലാ ഉപയോക്തൃ വിവരവും നഷ്‌ടപ്പെടുകയും ചെയ്യും."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"നിങ്ങൾ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ ഫോൺ അൺലോക്കുചെയ്യാൻ തെറ്റായി ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%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">"നിങ്ങളുടെ പിൻ <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ ടാബ്‌ലെറ്റ് അൺലോക്കുചെയ്യാൻ തെറ്റായി ശ്രമിച്ചു. ടാബ്‌ലെറ്റ് ഇപ്പോൾ ഫാക്‌ടറി സ്ഥിരമായതിലേക്ക് പുനസജ്ജീകരിക്കും."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"പദം"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ലിങ്ക്"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ലൈൻ"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ഫാക്‌ടറി പരിശോധന പരാജയപ്പെട്ടു"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"/system/app എന്നതിൽ ഇൻസ്‌റ്റാൾ ചെയ്‌ത പാക്കേജുകൾക്കായി മാത്രം FACTORY_TEST പ്രവർത്തനം പിന്തുണയ്‌ക്കുന്നു."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST പ്രവർത്തനം നൽകുന്ന പാക്കേജൊന്നും തന്നെ കണ്ടെത്തിയില്ല."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ഉപയോക്തൃനാമമോ പാസ്‌വേഡോ അസാധുവാണ്."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"നിങ്ങളുടെ ഉപയോക്തൃനാമമോ പാസ്‌വേഡോ മറന്നുപോയോ?\n"<b>"google.com/accounts/recovery"</b>" സന്ദർശിക്കുക."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"അക്കൗണ്ട് പരിശോധിക്കുന്നു…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"നിങ്ങളുടെ പിൻ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ടൈപ്പുചെയ്‌തു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"നിങ്ങളുടെ പാസ്‌വേഡ് <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ടൈപ്പുചെയ്‌തു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"നിങ്ങളുടെ പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"നിങ്ങൾ ഫോൺ അൺലോക്കുചെയ്യാൻ തവണ <xliff:g id="NUMBER_0">%d</xliff:g> തെറ്റായി ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി വിജയിച്ചില്ലെങ്കിൽ, ടാബ്‌ലെറ്റ് ഫാക്‌ടറി ഡിഫോൾട്ടിലേക്ക് പുനഃസജ്ജികരിക്കുകയും ഉപയോക്തൃ ഡാറ്റയെല്ലാം നഷ്‌ടപ്പെടുകയും ചെയ്യും."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ടിവി അൺലോക്കുചെയ്യൽ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി ചെയ്‌തു. <xliff:g id="NUMBER_1">%d</xliff:g>-ൽ കൂടുതൽ പരാജയപ്പെട്ട ശ്രമങ്ങൾക്കുശേഷം, ടിവി ഫാക്‌ടറി സ്ഥിരതയിലേക്ക് പുനഃസജ്ജീകരിക്കുകയും എല്ലാ ഉപയോക്തൃ വിവരവും നഷ്‌ടപ്പെടുകയും ചെയ്യും."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"നിങ്ങൾ ഫോൺ അൺലോക്കുചെയ്യാൻ തവണ <xliff:g id="NUMBER_0">%d</xliff:g> തെറ്റായി ശ്രമിച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി വിജയിച്ചില്ലെങ്കിൽ, ഫോൺ ഫാക്‌ടറി ഡിഫോൾട്ടിലേക്ക് പുനഃസജ്ജികരിക്കുകയും ഉപയോക്തൃ ഡാറ്റയെല്ലാം നഷ്‌ടപ്പെടുകയും ചെയ്യും."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"നിങ്ങളുടെ പിൻ <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_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">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി വിജയിച്ചില്ലെങ്കിൽ, ഒരു ഇമെയിൽ അക്കൗണ്ട് ഉപയോഗിച്ച് ടാബ്‌ലെറ്റ് അൺലോക്ക് ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> സെക്കൻഡിനുള്ള വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"നിങ്ങൾ അൺലോക്കുചെയ്യൽ പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g>-ൽ കൂടുതൽ പരാജയപ്പെട്ട ശ്രമങ്ങൾക്കുശേഷം, ഒരു ഇമെയിൽ അക്കൗണ്ട് ഉപയോഗിച്ച് നിങ്ങളുടെ ടിവി അൺലോക്കുചെയ്യുന്നതിന് ആവശ്യപ്പടും. \n\n <xliff:g id="NUMBER_2">%d</xliff:g> സെക്കൻഡിനുള്ളിൽ വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"നിങ്ങളുടെ അൺലോക്ക് പാറ്റേൺ <xliff:g id="NUMBER_0">%d</xliff:g> തവണ തെറ്റായി വരച്ചു. <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി വിജയിച്ചില്ലെങ്കിൽ, ഒരു ഇമെയിൽ അക്കൗണ്ട് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 589c559..ef01668 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Та нууц үгээ <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Та зурган түгжээгээ <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оруулсан байна. Та дахиж <xliff:g id="NUMBER_1">%d</xliff:g> удаа буруу оруулсны дараагаар та телевизийнхээ түгжээг Google акаунтандаа нэвтэрч тайлах шаардлагатай болно.\n\n Та <xliff:g id="NUMBER_2">%d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Та <xliff:g id="NUMBER_0">%d</xliff:g> удаа телевизийнхээ түгжээг тайлах оролдлогыг амжилтгүй хийсэн байна. Та дахиж <xliff:g id="NUMBER_1">%d</xliff:g> удаа буруу оруулсны дараагаар телевизийн тохиргоо үйлдвэрээс гарсан анхны тохиргоонд шилжих бөгөөд хэрэглэгчийн бүх мэдээлэл устах болно."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Та таблетыг <xliff:g id="NUMBER">%d</xliff:g> удаа тайлах гэж буруу оролдлоо. Таблет одоо үйлдвэрийн үндсэн утгаараа тохируулагдах болно."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"үг"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"холбоос"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"Мөр"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Үйлдлвэрийн тест бүтэлгүйтэв"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST үйлдэл нь зөвхөн /system/app-д суусан багцуудад дэмжигдэнэ."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST үйлдлийг хангах багц олдсонгүй."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Хэрэглэгчийн нэр эсвэл нууц үг буруу."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Хэрэглэгчийн нэр нууц үгээ мартсан уу?\n"<b>"google.com/accounts/recovery"</b>"-д зочилно уу."</string>
     <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">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Та <xliff:g id="NUMBER_0">%d</xliff:g> удаа телевизийнхээ түгжээг тайлах оролдлогыг амжилтгүй хийсэн байна. Та дахиж <xliff:g id="NUMBER_1">%d</xliff:g> удаа буруу оруулсны дараагаар телевизийн тохиргоо үйлдвэрээс гарсан анхны тохиргоонд шилжих бөгөөд хэрэглэгчийн бүх мэдээлэл устах болно."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол утас үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</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">"Та 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_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">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд имэйл акаунт шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Та зурган түгжээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оруулсан байна. <xliff:g id="NUMBER_1">%d</xliff:g> удаа буруу оруулсны дараагаар та телевизийнхээ түгжээг и-мэйл дансаа ашиглан тайлах хэрэгтэй болно.\n\n Та <xliff:g id="NUMBER_2">%d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та утсаа тайлахын тулд имэйл акаунтаа ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 5250bcb..4e43265 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"वापरकर्ता मार्गदर्शक पहा किंवा कस्टमर केअरशी संपर्क साधा."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"सिम कार्ड लॉक केलेले आहे."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"सिम कार्ड अनलॉक करत आहे…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"आपण आपला संकेतशब्द <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"आपण आपला पिन <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%d</xliff:g> वेळा चुकीचा रेखांकित केला आहे. <xliff:g id="NUMBER_1">%d</xliff:g> अधिक अयशस्वी प्रयत्नांनंतर, आपल्याला आपले Google साइन इन वापरून आपला टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा आपला अनलॉक नमुना अयोग्यरित्या काढला आहे. आणखी <xliff:g id="NUMBER_1">%d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला आपले Google साइन इन वापरून आपला टीव्ही अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%d</xliff:g> वेळा चुकीचा रेखांकित केला आहे. <xliff:g id="NUMBER_1">%d</xliff:g> अधिक अयशस्वी प्रयत्नांनंतर, आपल्याला आपले Google साइन इन वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा टॅब्लेट अनलॉक करण्याचे चुकीचे प्रयत्न केले. आणखी <xliff:g id="NUMBER_1">%d</xliff:g> अयशस्वी प्रयत्नांनंतर, टॅब्लेट फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि सर्व वापरकर्ता डेटा गमावला जाईल."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा टीव्ही अनलॉक करण्याचा अयोग्यरित्या प्रयत्न केला. आणखी <xliff:g id="NUMBER_1">%d</xliff:g> अयशस्वी प्रयत्नांनंतर, टीव्ही फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि सर्व वापरकर्ता डेटा गमावेल."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा फोन अनलॉक करण्याचे चुकीचे प्रयत्न केले. आणखी <xliff:g id="NUMBER_1">%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">"आपण आपला पिन <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"आपण <xliff:g id="NUMBER">%d</xliff:g> वेळा टॅब्लेट अनलॉक करण्याचे चुकीचे प्रयत्न केले. टॅब्लेट आता फॅक्टरी डीफॉल्टवर रीसेट केले जाईल."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"शब्द"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"दुवा"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"रेखा"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"फॅक्टरी चाचणी अयशस्वी"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया फक्त /सिस्टम/अॅप मध्ये स्थापित केलेल्या पॅकेजसाठी समर्थित आहे."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST क्रिया प्रदान करणारे कोणतेही पॅकेज आढळले नाही."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"अवैध वापरकर्तानाव किंवा संकेतशब्द."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"आपले वापरकर्तानाव किंवा संकेतशब्द विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"खाते तपासत आहे…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आपण आपला पिन <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आपण आपला संकेतशब्द <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने टाइप केला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यरितीने काढला आहे. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा टॅब्लेट अनलॉक करण्याचा अयोग्यपणे प्रयत्न केला. <xliff:g id="NUMBER_1">%d</xliff:g> आणखी अयशस्वी प्रयत्नांनंतर, टॅब्लेट फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि वापरकर्ता डेटा गमावेल."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा टीव्ही अनलॉक करण्याचा अयोग्यरित्या प्रयत्न केला. आणखी <xliff:g id="NUMBER_1">%d</xliff:g> अयशस्वी प्रयत्नांनंतर, टीव्ही फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि सर्व वापरकर्ता डेटा गमावेल."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा फोन अनलॉक करण्याचा अयोग्यपणे प्रयत्न केला. <xliff:g id="NUMBER_1">%d</xliff:g> आणखी अयशस्वी प्रयत्नांनंतर, फोन फॅक्टरी डीफॉल्टवर रीसेट केला जाईल आणि वापरकर्ता डेटा गमावेल."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आपण आपला पिन <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_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">%d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला ईमेल खाते वापरून आपला टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"आपण <xliff:g id="NUMBER_0">%d</xliff:g> वेळा आपला अनलॉक नमुना अयोग्यरित्या काढला आहे. आणखी <xliff:g id="NUMBER_1">%d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला ईमेल खाते वापरून आपला टीव्ही अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंदांनी पुन्हा प्रयत्न करा."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपण आपला अनलॉक नमुना <xliff:g id="NUMBER_0">%d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%d</xliff:g> अयशस्वी प्रयत्नांनंतर, आपल्याला ईमेल खाते वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index b3e9ac7..a1955bf 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Lihat Panduan Pengguna atau hubungi Penjagaan Pelanggan."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kad SIM dikunci."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Membuka kunci kad SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nSila cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah menaip kata laluan yang salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah menaip PIN yang salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Anda telah tersilap lukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta untuk membuka kunci TV anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam masa <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Sila cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Anda telah mencuba membuka kunci TV secara tidak betul sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, TV akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nSila cuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah menaip kata laluan yang salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah menaip PIN yang salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Anda telah tersilap lukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta untuk membuka kunci TV anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam masa <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Sila cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Anda telah mencuba membuka kunci TV secara tidak betul sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, TV akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Anda telah cuba membuka kunci TV secara tidak betul sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. TV kini akan ditetapkan semula kepada tetapan lalai kilang."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula kepada tetapan lalai kilang."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"perkataan"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"pautan"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"baris"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Ujian kilang gagal"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Tindakan FACTORY_TEST hanya disokong untuk pakej yang dipasangkan dalam /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Tiada pakej yang menyediakan tindakan FACTORY_TEST ditemui."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau kata laluan tidak sah."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?\nLawati"<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Menyemak akaun…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN yang salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan yang salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Anda telah cuba membuka kunci TV secara tidak betul sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, TV akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN yang salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan yang salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Anda telah cuba membuka kunci TV secara tidak betul sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, TV akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Anda telah cuba membuka kunci TV secara tidak betul sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. TV kini akan ditetapkan semula kepada tetapan lalai kilang."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula ke tetapan lalai kilang."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Anda telah tersilap lukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta untuk membuka kunci TV anda menggunakan akaun e-mel.\n\n Cuba lagi dalam masa <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Anda telah tersilap lukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta untuk membuka kunci TV anda menggunakan akaun e-mel.\n\n Cuba lagi dalam masa <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alih keluar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Naikkan kelantangan melebihi paras yang disyokorkan?\n\nMendengar pada kelantangan yang tinggi untuk tempoh yang lama boleh merosakkan pendengaran anda."</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 8019ecb..a913e38 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"သုံးစွဲသူ လမ်းညွှန်ကို ကြည့်ပါ သို့မဟုတ် ဖောက်သည်များ စောင့်ရှောက်ရေး ဌာနကို ဆက်သွယ်ပါ။"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"ဆင်းမ်ကဒ် သော့ကျနေပါသည်"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"ဆင်းမ်ကဒ် ကို သော့ဖွင့်နေပါသည်"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"သင်သည် သော့ဖွင့် ပုံစံကို<xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ \n\nထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g>စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"သင်သည် စကားဝှက်ကို  <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရိုက်ခဲ့ပြီ။ \n\n ထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"သင်သည် သင်၏ PIN <xliff:g id="NUMBER_0">%d</xliff:g>ကို ကြိမ် မမှန်မကန် ရိုက်ခဲ့ပြီ။ \n\n ထပ်ပြီးတော့ <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"သင်သည် သော့ဖွင့် ပုံစံကို<xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> မအောင်မြင်သည့် ကြိုးပမ်းမှု နောက်မှာ၊ သင်၏ တက်ဘလက်ကို Google လက်မှတ်ထိုး ဝင်မှုဖြင့် ဖွင့်ရန် တောင်းဆိုခံရမည်။ \n\n ထပ်ပြီး <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ သင့် Google လက်မှတ်ထိုးဝင်ရောက်သည့် အချက်အလက်ကို သုံးလျက် တီဗွီအား သော့ဖွင့်ရမည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"သင်သည် သော့ဖွင့် ပုံစံကို <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မမှန်မကန် ရေးဆွဲခဲ့သည်။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> မအောင်မြင်သည့် ကြိုးပမ်းမှု နောက်မှာ၊ သင်၏ ဖုန်းကို Google လက်မှတ်ထိုး ဝင်မှုဖြင့် ဖွင့်ရန် တောင်းဆိုခံရမည်။ \n\n ထပ်ပြီး <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့် အကြာမှာ စမ်းကြည့်ပါ။"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"သင့်Tabletအား မှားယွင်းစွာ <xliff:g id="NUMBER_0">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားနေပါသည်။ နောက်ထပ်<xliff:g id="NUMBER_1">%d</xliff:g>ကြိမ်မအောင်မြင်ပါက မူလစက်ရုံ အနေအထားသို့ပြန်လည်ရောက်ရှိကာ အသုံးပြုသူ၏ဒေတာအားလုံးဆုံးရှုံးပါမည်။"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။<xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်ပြီး အသုံးပြုသူ၏ အချက်အလက်များ ပျောက်သွားမည်ဖြစ်၏။"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"သင့်ဖုန်းအား မှားယွင်းစွာ <xliff:g id="NUMBER_0">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားနေပါသည်။ နောက်ထပ်<xliff:g id="NUMBER_1">%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_at_wipe" product="tablet" msgid="6128106399745755604">"သင့်Tabletအား မှားယွင်းစွာ <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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"သင့်Tabletအား မှားယွင်းစွာ <xliff:g id="NUMBER">%d</xliff:g>ကြိမ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ယခုဖုန်းကိုမူလစက်ရုံအနေအထားသို့ပြန်လည်ရောက်ရှိပါမည်။"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"စာလုံး"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"အ​ခြား​စာ​မျက်​နှာ​သို့​ကွင်း​ဆက်"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"စာကြောင်း"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"စက်ရုံစမ်းသပ်ခြင်းမအောင်မြင်ပါ"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"စက်ရုံစမ်းသပ်မှုမှာ စနစ်/အပ်ပလီကေးရှင်း ထည့်သွင်းထားသောpackageများကိုသာ ပံ့ပိုးမှုပေးသည်။."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"စက်ရုံစမ်းသပ်မှုအားလုပ်ဆောင်ရန် မည်သည့်packageမှ မတွေ့ပါ။"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"အသုံးပြုသူ အမည် သို့  စကားဝှက်မမှန်ကန်ပါ"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"သင် သုံးစွဲသူ အမည် သို့ စကားဝှက်အားမေ့နေပါသလား။\n"<b>"google.com/accounts/recovery"</b>" သို့ သွားရောက်ပါ"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"အကောင့်ကို စစ်ဆေးနေစဉ်..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"သင် ပင် နံပါတ်ကို အမှားကို <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် ရိုက်ထည့်ပြီးပါပြီ။ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့် အကြာတွင် ပြန်လည်ကြိုးစားပါ"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"သင်သည် စကားဝှက်ကို  <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားရိုက်ပြီးပါပြီ။ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာ ပြန်လည်ကြိုးစားပါ"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"သင် ပုံစံဆွဲ သော့ဖွင့်ခြင်းကို <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ်မြောက် မအောင်မြင်ပါ။ \n\n<xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အကြာတွင် ပြန်လည် ကြိုးစားပါ"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"သင့်တက်ဘလက်အား သော့ဖွင့်ရန် မအောင်မြင်သော အကြိမ်ရေ <xliff:g id="NUMBER_0">%d</xliff:g>  ကြိုးစားပြီးပါပြီ။ နောက်ထပ်  <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မအောင်မြင်ပါက၊ တက်ဘလက်က စက်ရုံထွက် အခြေအနေကို ပြန်လည် ရောက်ရှိသွားမည်ဖြစ်ပြီး ဒေတာအားလုံး ဆုံးရှုံးသွားပါမည်။"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"တီဗွီဖွင့်ရန် သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားယွင်းစွာ ကြိုးစားပြီးဖြစ်၏။<xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ တီဗွီသည် စက်ရုံထုတ်အခြေအနေသို့ ပြန်လည်ရောက်ရှိသွားမည်ဖြစ်ပြီး အသုံးပြုသူ၏ အချက်အလက်များ ပျောက်သွားမည်ဖြစ်၏။"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"သင့်ဖုန်းအား သော့ဖွင့်ရန် မအောင်မြင်သော အကြိမ်ရေ <xliff:g id="NUMBER_0">%d</xliff:g> ကြိုးစားပြီးပါပြီ။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မအောင်မြင်ပါက၊ ဖုန်းက စက်ရုံထွက် အခြေအနေကို ပြန်လည် ရောက်ရှိသွားမည်ဖြစ်ပြီး ဒေတာအားလုံး ဆုံးရှုံးသွားပါမည်။"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"သင် ပင် နံပါတ်ကို အမှားကို <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_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">%d</xliff:g> အကြိမ် မှန်ကန်စွာ မပြုလုပ်နိုင်ပါ။  နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မမှန်ကန်ပါက သင့်တက်ဘလက်အား အီးမေးလ်အသုံးပြု၍ သော့ဖွင့်ရန် တောင်းဆိုပါလိမ့်မည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ပြန်လည် ကြိုးစားပါ"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ပုံဖော်၍ သော့ဖွင့်ခြင်းအား သင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် မှားဆွဲပြီးဖြစ်၏။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ် ကြိုးစားပြီးနောက် မအောင်မြင်ပါက၊ သင့် အီးမေးအက​ောင့်အားသုံးလျက် သော့ဖွင့်ရန် ပြောလိမ့်မည်။ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> စက္ကန့်အကြာတွင် ထပ်မံကြိုးစားပါ။"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"သင် ပုံဖော်၍သော့ဖွင့်ခြင်းကို <xliff:g id="NUMBER_0">%d</xliff:g> အကြိမ် မှန်ကန်စွာ မပြုလုပ်နိုင်ပါ။ နောက်ထပ် <xliff:g id="NUMBER_1">%d</xliff:g> အကြိမ် မမှန်ကန်ပါက သင့်ဖုန်းအား အီးမေးလ်အသုံးပြု၍ သော့ဖွင့်ရန် တောင်းဆိုပါလိမ့်မည်။ \n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 307ff2f..74d7c98 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -229,7 +229,7 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"se kontaktene dine"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Posisjon"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"tilgang til enhetens plassering"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"få tilgang til enhetens plassering"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"åpne kalenderen din"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Les i brukerhåndboken eller kontakt brukerstøtten."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortet er låst."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Låser opp SIM-kort…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har oppgitt feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har skrevet inn feil passord <xliff:g id="NUMBER_0">%d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har skrevet inn feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp nettbrettet ved hjelp av Google-påloggingsinformasjonen din.\n\nPrøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk til blir du bedt om å låse opp TV-en ved hjelp av Google-pålogging.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp telefonen ved hjelp av Google-påloggingsinformasjonen din.\n\nPrøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har foretatt <xliff:g id="NUMBER_0">%d</xliff:g> mislykkede opplåsinger av nettbrettet. Etter <xliff:g id="NUMBER_1">%d</xliff:g> flere mislykkede forsøk, blir nettbrettet tilbakestilt til fabrikkinnstillingene, og alle brukerdata går tapt."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har gjort feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger i forsøk på å låse opp TV-en. Etter <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk til blir TV-en tilbakestilt til fabrikkstandard, slik at alle brukerdataene går tapt."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har foretatt <xliff:g id="NUMBER_0">%d</xliff:g> mislykkede opplåsinger av telefonen. Etter <xliff:g id="NUMBER_1">%d</xliff:g> flere mislykkede forsøk, blir telefonen tilbakestilt til fabrikkinnstillingene, og alle brukerdata går tapt."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har oppgitt feil opplåsingsmønster <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har skrevet inn feil passord <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har skrevet inn feil PIN-kode <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp nettbrettet ved hjelp av Google-påloggingsinformasjonen din.\n\nPrøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøk til blir du bedt om å låse opp TV-en ved hjelp av Google-pålogging.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp telefonen ved hjelp av Google-påloggingsinformasjonen din.\n\nPrøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har foretatt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislykkede opplåsinger av nettbrettet. Etter <xliff:g id="NUMBER_1">%2$d</xliff:g> flere mislykkede forsøk, blir nettbrettet tilbakestilt til fabrikkinnstillingene, og alle brukerdata går tapt."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har gjort feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger i forsøk på å låse opp TV-en. Etter <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøk til blir TV-en tilbakestilt til fabrikkstandard, slik at alle brukerdataene går tapt."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har foretatt <xliff:g id="NUMBER_0">%1$d</xliff:g> mislykkede opplåsinger av telefonen. Etter <xliff:g id="NUMBER_1">%2$d</xliff:g> flere mislykkede forsøk, blir telefonen tilbakestilt til fabrikkinnstillingene, og alle brukerdata går tapt."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du har foretatt <xliff:g id="NUMBER">%d</xliff:g> mislykkede opplåsinger av nettbrettet. Nettbrettet blir nå tilbakestilt til fabrikkinnstillingene."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Du har gjort feil <xliff:g id="NUMBER">%d</xliff:g> ganger i forsøk på å låse opp TV-en. TV-en blir nå tilbakestilt til fabrikkstandard."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Du har foretatt <xliff:g id="NUMBER">%d</xliff:g> mislykkede opplåsinger av telefonen. Telefonen blir nå tilbakestilt til fabrikkinnstillingene."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ord"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linje"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabrikktesten feilet"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldig brukernavn eller passord."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt brukernavnet eller passordet?\nGå til "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Sjekker kontoen ..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles nettbrettet til fabrikkstandard og all data går tapt."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har gjort feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger i forsøk på å låse opp TV-en. Etter <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk til blir TV-en tilbakestilt til fabrikkstandard, slik at alle brukerdataene går tapt."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles telefonen til fabrikkstandard og all data går tapt."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> gale forsøk, tilbakestilles nettbrettet til fabrikkstandard og all data går tapt."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har gjort feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger i forsøk på å låse opp TV-en. Etter <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøk til blir TV-en tilbakestilt til fabrikkstandard, slik at alle brukerdataene går tapt."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> gale forsøk, tilbakestilles telefonen til fabrikkstandard og all data går tapt."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Du har gjort feil <xliff:g id="NUMBER">%d</xliff:g> ganger i forsøk på å låse opp TV-en. TV-en blir nå tilbakestilt til fabrikkstandard."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk til blir du bedt om å låse opp TV-en ved hjelp av en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøk til blir du bedt om å låse opp TV-en ved hjelp av en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Vil du øke volumet til over anbefalt nivå?\n\nHvis du hører på et høyt volum over lengre perioder, kan det skade hørselen din."</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index f18cd74..6fe9c4d 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"तपाईंले गलत तरिकाले आफ्नो पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नुभयो। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। पछि <xliff:g id="NUMBER_1">%d</xliff:g> थप असफल कोसिसहरू, तपाईँको Google साइन इन प्रयोग गरी तपाईँको ट्याब्लेट अनलक गर्न भनिने छ।\n\n  <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा फरि प्रयास गर्नुहोस्।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"तपाईंले गलत तरिकाले आफ्नो अनलक ढाँचा झिक्नु भएकोछ <xliff:g id="NUMBER_0">%d</xliff:g> पटक। <xliff:g id="NUMBER_1">%d</xliff:g> थप असफल प्रयासहरू पछि तपाईँलाई आफ्नो TV तपाईँको Google साइन इन प्रयोग गरी अनलक गर्न आग्रह गरिनेछ। \n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"तपाईँले <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत तरिकाले तपाईँको अनलक ढाँचालाई कोर्नु भएको छ। पछि <xliff:g id="NUMBER_1">%d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, तपाईँलाई तपाईँको फोन Google साइन इन प्रयोग गरेर अनलक गर्नको लागि सोधिने छ। \n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"तपाईँले <xliff:g id="NUMBER_0">%d</xliff:g> पटक ट्याब्लेटलाई अनलक गर्नको लागि गलत तरिकाले कोशिस गर्नुभएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, ट्याब्लेट फ्याट्रि पूर्वनिर्धारितमा पुनःसेट हुने छ र सबै प्रयोगकर्ता डेटा हराउने छन्।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"तपाईंले गलत तरिकाले TV अनलक गर्ने प्रयास गर्नुभएको छ <xliff:g id="NUMBER_0">%d</xliff:g> पटक। <xliff:g id="NUMBER_1">%d</xliff:g> थप असफल प्रयासहरू पछि TV कारखानाको पूर्वनिर्धारित सेटिङमा रिसेट हुनेछ र सबै प्रयोगकर्ता डेटा नष्ट हुनेछन्।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"तपाईंले गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक फोन अनलक गर्ने प्रयत्न गर्नुभयो। <xliff:g id="NUMBER_1">%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> थप असफल प्रयासहरू पछि तपाईँलाई आफ्नो TV तपाईँको 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">"तपाईंले गलत तरिकाले TV अनलक गर्ने प्रयास गर्नुभएको छ <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक। <xliff:g id="NUMBER_1">%2$d</xliff:g> थप असफल प्रयासहरू पछि TV कारखानाको पूर्वनिर्धारित सेटिङमा रिसेट हुनेछ र सबै प्रयोगकर्ता डेटा नष्ट हुनेछन्।"</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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"तपाईँले ट्यब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER">%d</xliff:g> पटक प्रयास गर्नु भएको छ। अब ट्याब्लेटलाई पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ।"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"तपाईंले गलत तरिकाले TV अनलक गर्ने प्रयास गर्नु भएको छ <xliff:g id="NUMBER">%d</xliff:g> पटक। TV अब कारखानाको पूर्वनिर्धारित सेटिङमा रिसेट गरिनेछ।"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"तपाईंले गलत तरिकाले फोन <xliff:g id="NUMBER">%d</xliff:g> पटक अनलक गर्ने प्रयत्न गर्नुभयो। अब फोन फ्याक्ट्रि पूर्वनिर्धारितमा पुनःसेट हुने छ।"</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"शब्द"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"लिङ्क"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"लाइन"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"कार्यशाला परीक्षण असफल भयो।"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST कार्रवाइले /system/app मा स्थापित प्याकेजहरूको लागि मात्र समर्थन गर्छ।"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"कुनै प्याकेज फेला पार्न सकिएन जसले FACTORY_TEST कार्य प्रदान गर्दछ।"</string>
@@ -1291,18 +1289,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"अमान्य प्रयोगकर्तानाम वा पासवर्ड।"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"के तपाईँले उपयोगकर्ता नाम वा पासवर्ड बिर्सनुभयो?\n"<b>"google.com/accounts/recovery"</b>" मा जानुहोस्।"</string>
     <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">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"तपाईंले गलत तरिकाले TV अनलक गर्ने प्रयास गर्नु भएको छ <xliff:g id="NUMBER_0">%d</xliff:g> पटक। <xliff:g id="NUMBER_1">%d</xliff:g> थप असफल प्रयासहरू पछि, TV कारखानाको पूर्वनिर्धारित सेटिङमा रिसेट हुनेछ र सबै प्रयोगकर्ता डेटा नष्ट हुनेछन्।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"तपाईँले गलतसँग फोनलाई अनलक गर्न <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भयो। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल कोसिसहरू, फोनलाई पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</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_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">"तपाईंले गलत तरिकाले TV अनलक गर्ने प्रयास गर्नु भएको छ <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक। <xliff:g id="NUMBER_1">%2$d</xliff:g> थप असफल प्रयासहरू पछि, TV कारखानाको पूर्वनिर्धारित सेटिङमा रिसेट हुनेछ र सबै प्रयोगकर्ता डेटा नष्ट हुनेछन्।"</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">"तपाईंले गलत तरिकाले TV अनलक गर्ने प्रयास गर्नु भएको छ <xliff:g id="NUMBER">%d</xliff:g> पटक। TV अब कारखानाको पूर्वनिर्धारित सेटिङमा रिसेट हुनेछ।"</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">%d</xliff:g> पटक कोर्नुभयो। <xliff:g id="NUMBER_1">%d</xliff:g> विफल प्रयत्नहरू पछि, तपाईंलाई आफ्नो ट्याब्लेट इमेल खाता प्रयोग गरेर अनलक गर्न सोधिने छ।\n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डहरूमा।"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"तपाईंले गलत तरिकाले आफ्नो अनलक ढाँचालाई झिक्नु भएको छ <xliff:g id="NUMBER_0">%d</xliff:g> पटक। <xliff:g id="NUMBER_1">%d</xliff:g> थप असफल प्रयासहरू पछि तपाईँलाई इमेल खाता खोली तपाईँको  TV अनलक गर्नका लागि आग्रह गरिनेछ।\n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा।"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"तपाईँले आफ्नो अनलक ढाँचा गलत रूपमा <xliff:g id="NUMBER_0">%d</xliff:g> पटक तान्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> धेरै असफल प्रयासहरूपछि, तपाईँलाई एउटा इमेल खाताको प्रयोग गरेर तपाईँको फोन अनलक गर्न सोधिने छ।\n\n फेरि <xliff:g id="NUMBER_2">%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> थप असफल प्रयासहरू पछि तपाईँलाई इमेल खाता खोली तपाईँको  TV अनलक गर्नका लागि आग्रह गरिनेछ।\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>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index c12edc9c..e4f388f 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Raadpleeg de gebruikershandleiding of neem contact op met de klantenservice."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart is vergrendeld."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaart ontgrendelen..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Je hebt je pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met je inloggegevens voor Google.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Je hebt nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getypt. \n\nProbeer het  opnieuw over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Je hebt je pincode <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met je inloggegevens voor Google.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen met je aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%1$d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Je hebt nu <xliff:g id="NUMBER_0">%1$d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Je hebt op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"woord"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"lijn"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabriekstest mislukt"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"De actie FACTORY_TEST wordt alleen ondersteund voor pakketten die zijn geïnstalleerd in /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Er is geen pakket gevonden dat de actie FACTORY_TEST levert."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikersnaam of wachtwoord."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u je gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Account controleren…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Je hebt je pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%d</xliff:g> seconden."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Je hebt <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Je hebt nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Je hebt je pincode <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getypt. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. \n\nProbeer het opnieuw over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Je hebt <xliff:g id="NUMBER_0">%1$d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Je hebt op onjuiste wijze <xliff:g id="NUMBER_0">%1$d</xliff:g> keer geprobeerd de tv te ontgrendelen. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onjuiste pogingen, wordt de tv hersteld naar de fabriekswaarden en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Je hebt nu <xliff:g id="NUMBER_0">%1$d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Je hebt op onjuiste wijze <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tv te ontgrendelen. De tv wordt nu hersteld naar de fabrieksinstellingen."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met een e-mailaccount.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%d</xliff:g> seconden."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt u gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog <xliff:g id="NUMBER_1">%2$d</xliff:g> onjuiste pogingen, wordt je gevraagd je tv te ontgrendelen met een e-mailaccount.\n\n Probeer het opnieuw over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt u gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwijderen"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls u langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 7d60746..96343d8 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ਤੁਸੀਂ ਆਪਣਾ PIN <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣੀ ਟੈਬਲੇਟ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ। \n\n <xliff:g id="NUMBER_2">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n  <xliff:g id="NUMBER_2">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫੋਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%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 ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\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> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੌਬਲੇਟ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗੀ।"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ।"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫੋਨ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ।"</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ਸ਼ਬਦ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ਲਿੰਕ"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ਲਾਈਨ"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ਫੈਕਟਰੀ ਜਾਂਚ ਅਸਫਲ"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ਕਿਰਿਆ ਕੇਵਲ /ਸਿਸਟਮ/ਐਪ ਵਿੱਚ ਇੰਸਟੌਲ ਕੀਤੇ ਪੈਕੇਜਾਂ ਲਈ ਸਮਰਥਿਤ ਹੈ।"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"ਅਜਿਹਾ ਕੋਈ ਪੈਕੇਜ ਨਹੀਂ ਮਿਲਿਆ ਜੋ FACTORY_TEST ਕਿਰਿਆ ਮੁਹੱਈਆ ਕਰਦਾ ਹੈ।"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ਅਪ੍ਰਮਾਣਿਕ ਉਪਭੋਗਤਾ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ।"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਉਪਭੋਗਤਾ ਨਾਮ ਜਾਂ ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ ਹੋ?\n"<b>"google.com/accounts/recovery"</b>" ਤੇ ਜਾਓ।"</string>
     <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">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਫੋਨ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</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_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> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡਾਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</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> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈਟ ਹੋ ਜਾਏਗਾ।"</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">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣੀ ਟੈਬਲੇਟ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫੋਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%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> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index a1e9de8..ae06e33 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -684,15 +684,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Zapoznaj się z instrukcją obsługi lub skontaktuj się z działem obsługi klienta."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Karta SIM jest zablokowana."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odblokowywanie karty SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Wzór odblokowania został nieprawidłowo narysowany <xliff:g id="NUMBER_0">%d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> zostało wpisane nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> został wpisany nieprawidłowy PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Wzór odblokowania został <xliff:g id="NUMBER_0">%d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Wzór odblokowania narysowałeś niepoprawnie <xliff:g id="NUMBER_0">%d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach trzeba będzie odblokować telewizor przy użyciu danych logowania konta Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Wzór odblokowania został <xliff:g id="NUMBER_0">%d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Próbowano <xliff:g id="NUMBER_0">%d</xliff:g> razy nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Podałeś nieprawidłowe dane odblokowania telewizora <xliff:g id="NUMBER_0">%d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telewizor zostanie zresetowany do stanu fabrycznego, a wszystkie dane użytkownika zostaną skasowane."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Próbowano <xliff:g id="NUMBER_0">%d</xliff:g> razy nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Wzór odblokowania został nieprawidłowo narysowany <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> zostało wpisane nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> został wpisany nieprawidłowy PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Wzór odblokowania został <xliff:g id="NUMBER_0">%1$d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Wzór odblokowania narysowałeś niepoprawnie <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach trzeba będzie odblokować telewizor przy użyciu danych logowania konta Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Wzór odblokowania został <xliff:g id="NUMBER_0">%1$d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Próbowano <xliff:g id="NUMBER_0">%1$d</xliff:g> razy nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Podałeś nieprawidłowe dane odblokowania telewizora <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach telewizor zostanie zresetowany do stanu fabrycznego, a wszystkie dane użytkownika zostaną skasowane."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Próbowano <xliff:g id="NUMBER_0">%1$d</xliff:g> razy nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Próbowano <xliff:g id="NUMBER">%d</xliff:g> razy nieprawidłowo odblokować tablet. Tablet zostanie teraz zresetowany do ustawień fabrycznych."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Podałeś nieprawidłowe dane odblokowania telewizora <xliff:g id="NUMBER">%d</xliff:g> razy. Zostanie on teraz zresetowany do stanu fabrycznego."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Próbowano <xliff:g id="NUMBER">%d</xliff:g> razy nieprawidłowo odblokować telefon. Telefon zostanie teraz zresetowany do ustawień fabrycznych."</string>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"słowo"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"wiersz"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Nieudany test fabryczny"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Czynność FACTORY_TEST jest obsługiwana tylko dla pakietów zainstalowanych w katalogu /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nie znaleziono żadnego pakietu, który zapewnia działanie FACTORY_TEST."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nieprawidłowa nazwa użytkownika lub hasło."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nie pamiętasz nazwy użytkownika lub hasła?\nWejdź na "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Sprawdzam konto"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Wpisałeś nieprawidłowy kod PIN <xliff:g id="NUMBER_0">%d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Narysowałeś nieprawidłowy wzór odblokowania <xliff:g id="NUMBER_0">%d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Podałeś nieprawidłowe dane odblokowania telewizora <xliff:g id="NUMBER_0">%d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telewizor zostanie zresetowany do stanu fabrycznego, a wszystkie dane użytkownika zostaną skasowane."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Wpisałeś nieprawidłowy kod PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Narysowałeś nieprawidłowy wzór odblokowania <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Podałeś nieprawidłowe dane odblokowania telewizora <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach telewizor zostanie zresetowany do stanu fabrycznego, a wszystkie dane użytkownika zostaną skasowane."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Tablet zostanie teraz zresetowany do ustawień fabrycznych."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Podałeś nieprawidłowe dane odblokowania telewizora <xliff:g id="NUMBER">%d</xliff:g> razy. Zostanie on teraz zresetowany do stanu fabrycznego."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Telefon zostanie teraz zresetowany do ustawień fabrycznych."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Wzór odblokowania narysowałeś niepoprawnie <xliff:g id="NUMBER_0">%d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach trzeba będzie odblokować telewizor przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Wzór odblokowania narysowałeś niepoprawnie <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. Po jeszcze <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach trzeba będzie odblokować telewizor przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Usuń"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Zwiększyć głośność ponad zalecany poziom?\n\nSłuchanie głośno przez długi czas może uszkodzić Twój słuch."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 3015bfe..4d88275 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulte o Guia do usuário ou entre em contato com o Serviço de atendimento ao cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"O cartão SIM está bloqueado."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando o cartão SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes.\n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando seu login do Google.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes.\n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando seu login do Google.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será redefinida agora para os padrões de fábrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"palavra"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linha"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Falha no teste de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"A ação FACTORY_TEST é suportada apenas para pacotes instalados em /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nenhum pacote que forneça a ação FACTORY_TEST foi encontrado."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de usuário ou senha inválidos."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu seu nome de usuário ou senha?\nAcesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Verificando a conta..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será redefinida agora para os padrões de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando uma conta de e-mail.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando uma conta de e-mail.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index b8b8355..863b6e8 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulte o Manual de utilizador ou contacte a Assistência a Clientes."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"O cartão SIM está bloqueado."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"A desbloquear cartão SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escreveu a sua palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\n Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escreveu o seu número PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\n Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet com as suas credenciais de início de sessão do Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"O utilizador desenhou incorretamente a sua sequência de desbloqueio <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, é-lhe pedido que desbloqueie a sua TV através do seu início de sessão Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel com as suas credenciais de início de sessão do Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativa(s) sem êxito, as definições de origem do tablet serão repostas e todos os dados de utilizador serão perdidos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"O utilizador tentou desbloquear incorretamente a TV <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, a TV é reposta para as predefinições de fábrica e todos os dados do utilizador são perdidos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativa(s) sem êxito, as definições de origem do telemóvel serão repostas e todos os dados de utilizador serão perdidos."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escreveu a sua palavra-passe incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\n Tente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escreveu o seu número PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\n Tente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet com as suas credenciais de início de sessão do Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"O utilizador desenhou incorretamente a sua sequência de desbloqueio <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, é-lhe pedido que desbloqueie a sua TV através do seu início de sessão Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel com as suas credenciais de início de sessão do Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes de forma incorreta. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativa(s) sem êxito, as definições de origem do tablet serão repostas e todos os dados de utilizador serão perdidos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"O utilizador tentou desbloquear incorretamente a TV <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, a TV é reposta para as predefinições de fábrica e todos os dados do utilizador são perdidos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes de forma incorreta. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativa(s) sem êxito, as definições de origem do telemóvel serão repostas e todos os dados de utilizador serão perdidos."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tentou desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que serão repostas as respetivas definições de origem."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"O utilizador tentou desbloquear incorretamente a TV <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será agora reposta para as predefinições de fábrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que serão repostas as respetivas definições de origem."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"palavra"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linha"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"O teste de fábrica falhou"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"A acção FACTORY_TEST apenas é suportada para pacotes instalados em /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Não foi localizado qualquer pacote que forneça a acção FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de utilizador ou palavra-passe inválidos."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu-se do nome de utilizador ou da palavra-passe?\nAceda a "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"A verificar a conta…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escreveu o PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escreveu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"O utilizador tentou desbloquear incorretamente a TV <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, a TV é reposta para as predefinições de fábrica e todos os dados do utilizador são perdidos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escreveu o PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escreveu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"O utilizador tentou desbloquear incorretamente a TV <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, a TV é reposta para as predefinições de fábrica e todos os dados do utilizador são perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tentou desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"O utilizador tentou desbloquear incorretamente a TV <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será agora reposta para as predefinições de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"O utilizador desenhou incorretamente a sua sequência de desbloqueio <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, é-lhe pedido que desbloqueie a sua TV através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"O utilizador desenhou incorretamente a sua sequência de desbloqueio <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, é-lhe pedido que desbloqueie a sua TV através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Aumentar o volume acima do nível recomendado?\n\nOuvir com um volume elevado durante longos períodos poderá ser prejudicial para a sua audição."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 3015bfe..4d88275 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulte o Guia do usuário ou entre em contato com o Serviço de atendimento ao cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"O cartão SIM está bloqueado."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando o cartão SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes.\n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando seu login do Google.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes.\n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando seu login do Google.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será redefinida agora para os padrões de fábrica."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"palavra"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linha"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Falha no teste de fábrica"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"A ação FACTORY_TEST é suportada apenas para pacotes instalados em /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nenhum pacote que forneça a ação FACTORY_TEST foi encontrado."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de usuário ou senha inválidos."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu seu nome de usuário ou senha?\nAcesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Verificando a conta..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será redefinida agora para os padrões de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando uma conta de e-mail.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando uma conta de e-mail.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 0dc5cea..9af1378b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -201,7 +201,7 @@
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonul dvs. se va închide."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"Doriți să închideţi?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"Reporniţi în modul sigur"</string>
-    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Doriți să reporniţi în modul sigur? Astfel vor fi dezactivate toate aplicațiile terţă parte pe care le-aţi instalat. Acestea vor fi restabilite când reporniţi din nou."</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Doriți să reporniţi în modul sigur? Astfel vor fi dezactivate toate aplicațiile terţă parte pe care le-ați instalat. Acestea vor fi restabilite când reporniţi din nou."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"Nu există aplicații recente."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Opţiuni tablet PC"</string>
@@ -338,9 +338,9 @@
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesare comenzi suplimentare ale furnizorului locației"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite aplicației să acceseze comenzi suplimentare pentru furnizorul locației. Aplicația ar putea să utilizeze această permisiune pentru a influența operațiile GPS sau ale altor surse de locații."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"să acceseze locația exactă (bazată pe GPS și pe rețea)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Permite aplicației să obţină locaţia dvs. exactă utilizând sistemul GPS (Global Positioning System) sau surse de localizare prin rețele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locaţia dvs. și pot să consume mai multă energie a bateriei."</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Permite aplicației să obţină locația dvs. exactă utilizând sistemul GPS (Global Positioning System) sau surse de localizare prin rețele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locația dvs. și pot să consume mai multă energie a bateriei."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"să acceseze locația aproximativă (bazată pe rețea)"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Permite aplicației să obţină locaţia dvs. aproximativă. Această locație este dedusă de serviciile de localizare utilizând surse de localizare prin rețele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locaţia dvs. aproximativă."</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Permite aplicației să obţină locația dvs. aproximativă. Această locație este dedusă de serviciile de localizare utilizând surse de localizare prin rețele, cum ar fi cele prin turn de celule și Wi-Fi. Pentru a fi utilizate de aplicație, aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul dvs. Aplicaţiile pot utiliza această permisiune pentru a determina locația dvs. aproximativă."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modificare setări audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite aplicației să modifice setările audio globale, cum ar fi volumul și difuzorul care este utilizat pentru ieșire."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"înregistreze sunet"</string>
@@ -358,7 +358,7 @@
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"accesează serviciul de apelare IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Permite aplicației să folosească serviciul IMS pentru apeluri, fără intervenția dvs."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"citeşte starea și identitatea telefonului"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicației să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicația stabilește numărul de telefon și ID-urile de dispozitiv, dacă un apel este activ, precum și numărul de la distanţă conectat printr-un apel."</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicației să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicația stabilește numărul de telefon și ID-urile de dispozitiv, dacă un apel este activ, precum și numărul de la distanță conectat printr-un apel."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"împiedicarea computerului tablet PC să intre în repaus"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"împiedică intrarea televizorului în stare de inactivitate"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"împiedicare intrare telefon în repaus"</string>
@@ -378,11 +378,11 @@
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Permite aplicației să modifice fusul orar al televizorului."</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Permite aplicației să schimbe fusul orar al telefonului."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"găseşte conturi pe dispozitiv"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Permite aplicației să obţină lista de conturi cunoscute de tabletă. Aceasta poate include conturile create de aplicațiile pe care le-aţi instalat."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Permite aplicației să obţină lista de conturi cunoscute de tabletă. Aceasta poate include conturile create de aplicațiile pe care le-ați instalat."</string>
     <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Permite aplicației să obțină lista de conturi cunoscute de televizor. Aceasta poate include conturile create de aplicațiile pe care le-ați instalat."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Permite aplicației să obţină lista de conturi cunoscute de telefon. Aceasta poate include conturile create de aplicațiile pe care le-aţi instalat."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Permite aplicației să obţină lista de conturi cunoscute de telefon. Aceasta poate include conturile create de aplicațiile pe care le-ați instalat."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"vizualizează conexiunile la rețea"</string>
-    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Permite aplicației să vadă informaţiile despre conexiunile la rețea, cum ar fi reţelele existente și cele care sunt conectate."</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Permite aplicației să vadă informațiile despre conexiunile la rețea, cum ar fi reţelele existente și cele care sunt conectate."</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"să aibă acces deplin la rețea"</string>
     <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Permite aplicației să creeze socluri de rețea și să utilizeze protocoale de rețea personalizate. Browserul și alte aplicații oferă mijloacele de trimitere a datelor pe internet, astfel încât această permisiune nu este necesară pentru trimiterea datelor pe internet."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"modificare conectivitate în rețea"</string>
@@ -390,7 +390,7 @@
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"modificare conectivitate tethering"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permite aplicației să modifice starea de conectivitate prin tethering la rețea."</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"vizualizează conexiunile Wi-Fi"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permite aplicației să vadă informaţiile despre reţelele Wi-Fi, de ex. dacă o rețea Wi-Fi este activată, precum și numele dispozitivelor conectate la rețeaua Wi-Fi."</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permite aplicației să vadă informațiile despre reţelele Wi-Fi, de ex. dacă o rețea Wi-Fi este activată, precum și numele dispozitivelor conectate la rețeaua Wi-Fi."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"se conectează și se deconectează de la Wi-Fi"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Permite aplicației să se conecteze și să se deconecteze de la punctele de acces Wi-Fi, precum și să efectueze modificări în configuraţia dispozitivului pentru reţelele Wi-Fi."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"permitere recepţionare difuzare multiplă Wi-Fi"</string>
@@ -398,11 +398,11 @@
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Permite aplicației să primească pachetele trimise către toate dispozitivele dintr-o rețea Wi-Fi, utilizând adrese cu difuzare multiplă, nu doar televizorul dvs. Această funcție utilizează mai multă energie decât modul fără difuzare multiplă."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Permite aplicației să primească pachetele trimise către toate dispozitivele dintr-o rețea Wi-Fi, utilizând adrese cu difuzare multiplă, nu doar telefonul dvs. Această funcție utilizează mai multă energie decât modul fără difuzare multiplă."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"accesează setările Bluetooth"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite aplicației să configureze tableta Bluetooth locală, să descopere și să se împerecheze cu dispozitive la distanţă."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite aplicației să configureze tableta Bluetooth locală, să descopere și să se împerecheze cu dispozitive la distanță."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Permite aplicației să configureze televizorul Bluetooth local, precum și să descopere și să se asocieze cu dispozitive la distanță."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite aplicației să configureze telefonul Bluetooth local, să descopere și să se împerecheze cu dispozitive la distanţă."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite aplicației să configureze telefonul Bluetooth local, să descopere și să se împerecheze cu dispozitive la distanță."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"se conectează și se deconectează de la WiMAX"</string>
-    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Permite aplicației să stabilească dacă o rețea WiMAX este activată și să vadă informaţiile cu privire la toate reţelele WiMAX conectate."</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Permite aplicației să stabilească dacă o rețea WiMAX este activată și să vadă informațiile cu privire la toate reţelele WiMAX conectate."</string>
     <string name="permlab_changeWimaxState" msgid="340465839241528618">"schimbaţi starea WiMAX"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Permite aplicației să conecteze și să deconecteze tableta la și de la reţelele WiMAX."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Permite aplicației să conecteze și să deconecteze televizorul la și de la rețelele WiMAX."</string>
@@ -499,7 +499,7 @@
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setați reguli pentru parolă"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Stabiliți lungimea și tipul de caractere permise pentru parolele și codurile PIN de blocare a ecranului."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizați încercările de deblocare a ecranului"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitorizaţi numărul de parole incorecte introduse la deblocarea ecranului și blocaţi tableta sau ştergeţi datele acesteia dacă sunt introduse prea multe parole incorecte."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocaţi tableta sau ștergeți datele acesteia dacă sunt introduse prea multe parole incorecte."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați televizorul sau ștergeți toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați telefonul sau ștergeți toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați tableta sau ștergeți toate datele acestui utilizator dacă se introduc prea multe parole incorecte."</string>
@@ -683,15 +683,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consultaţi Ghidul de utilizare sau contactaţi Serviciul de relaţii cu clienţii."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Cardul SIM este blocat."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Se deblochează cardul SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, vi se va solicita să deblocați televizorul cu ajutorul datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Ați efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a televizorului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, televizorul va reveni la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, vi se va solicita să deblocați televizorul cu ajutorul datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul datelor de conectare la Google.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Aţi efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a televizorului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, televizorul va reveni la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Aţi efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a televizorului. Televizorul va reveni acum la setările prestabilite din fabrică."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Acesta va fi acum resetat la setările prestabilite din fabrică."</string>
@@ -716,7 +716,7 @@
     <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Modelul a fost desenat"</string>
     <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zonă model."</string>
     <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d din %3$d."</string>
-    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adăugaţi un widget."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adăugați un widget."</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Gol"</string>
     <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Zona de deblocare a fost extinsă."</string>
     <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zona de deblocare a fost restrânsă."</string>
@@ -743,8 +743,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"cuvânt"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"rând"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Testarea de fabrică nu a reuşit"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Acţiunea FACTORY_TEST este acceptată doar pentru pachetele instalate în /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nu s-a găsit niciun pachet care să ofere acțiunea FACTORY_TEST."</string>
@@ -785,8 +783,8 @@
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Permite aplicației să seteze o alarmă într-o aplicație de ceas cu alarmă instalată. Este posibil ca unele aplicații de ceas cu alarmă să nu implementeze această funcție."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"adăugare mesagerie vocală"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite aplicației să adauge mesaje în Mesaje primite în mesageria vocală."</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modificare permisiuni pentru locaţia geografică a browserului"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite aplicației să modifice permisiunile privind locaţia geografică a browserului. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a permite trimiterea informaţiilor privind locaţia către site-uri web arbitrare."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modificare permisiuni pentru locația geografică a browserului"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite aplicației să modifice permisiunile privind locația geografică a browserului. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a permite trimiterea informaţiilor privind locația către site-uri web arbitrare."</string>
     <string name="save_password_message" msgid="767344687139195790">"Doriți ca browserul să reţină această parolă?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Nu acum"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Reţineţi"</string>
@@ -806,8 +804,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"Trimiteți interogarea"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Căutare vocală"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Activați Explorați prin atingere?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcţia Explorați prin atingere. Când această funcție este activată, puteți auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteți efectua gesturi pentru a interacţiona cu tableta."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcţia Explorați prin atingere. Când această funcție este activată, puteți auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteți efectua gesturi pentru a interacţiona cu telefonul."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcția Explorați prin atingere. Când această funcție este activată, puteți auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteți efectua gesturi pentru a interacţiona cu tableta."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> doreşte să activeze funcția Explorați prin atingere. Când această funcție este activată, puteți auzi sau vedea descrieri pentru ceea ce se află sub degetul dvs. sau puteți efectua gesturi pentru a interacţiona cu telefonul."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"cu 1 lună în urmă"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Cu mai mult de 1 lună în urmă"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -848,7 +846,7 @@
       <item quantity="one">O oră</item>
     </plurals>
     <string name="VideoView_error_title" msgid="3534509135438353077">"Problemă video"</string>
-    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Acest fişier video nu este valid pentru a fi transmis în flux către acest dispozitiv."</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Acest fișier video nu este valid pentru a fi transmis în flux către acest dispozitiv."</string>
     <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Nu puteți reda acest videoclip"</string>
     <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -867,7 +865,7 @@
     <string name="copyUrl" msgid="2538211579596067402">"Copiați adresa URL"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"Selectați text"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Selectare text"</string>
-    <string name="addToDictionary" msgid="4352161534510057874">"Adăugaţi în dicţionar"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Adăugați în dicţionar"</string>
     <string name="deleteText" msgid="6979668428458199034">"Ștergeți"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Metodă de intrare"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acţiuni pentru text"</string>
@@ -897,8 +895,8 @@
     <string name="alwaysUse" msgid="4583018368000610438">"Se utilizează în mod prestabilit pentru această acţiune."</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"Utilizați altă aplicație"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Ștergeți setările prestabilite din Setări de sistem &gt; Aplicații &gt; Descărcate."</string>
-    <string name="chooseActivity" msgid="7486876147751803333">"Alegeţi o acţiune"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"Alegeţi o aplicație pentru dispozitivul USB"</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Alegeți o acţiune"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Alegeți o aplicație pentru dispozitivul USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Această acţiune nu poate fi efectuată de nicio aplicație."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
     <string name="aerr_application" msgid="932628488013092776">"Din păcate, <xliff:g id="APPLICATION">%1$s</xliff:g> s-a oprit."</string>
@@ -935,12 +933,12 @@
     <string name="old_app_action" msgid="493129172238566282">"Reveniţi la <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
     <string name="old_app_description" msgid="2082094275580358049">"Nu porniți aplicația nouă."</string>
     <string name="new_app_action" msgid="5472756926945440706">"Porniţi <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Opriți vechea aplicație fără să salvaţi."</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Opriți vechea aplicație fără să salvați."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> a depășit limita de memorie"</string>
     <string name="dump_heap_notification_detail" msgid="2075673362317481664">"Datele privind memoria au fost culese; atingeți pentru a trimite"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Trimiteți datele privind memoria?"</string>
     <string name="dump_heap_text" msgid="4809417337240334941">"Procesul <xliff:g id="PROC">%1$s</xliff:g> și-a depășit limita de memorie de <xliff:g id="SIZE">%2$s</xliff:g>. Sunt disponibile datele privind memoria, pe care le puteți trimite dezvoltatorului. Atenție: aceste date privind memoria pot conține informațiile personale la care aplicația are acces."</string>
-    <string name="sendText" msgid="5209874571959469142">"Alegeţi o acţiune pentru text"</string>
+    <string name="sendText" msgid="5209874571959469142">"Alegeți o acţiune pentru text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volum sonerie"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volum media"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Redare prin Bluetooth"</string>
@@ -1007,7 +1005,7 @@
     <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Acest lucru va genera costuri în contul dvs. mobil."</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Trimiteți"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Anulați"</string>
-    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Doresc să se reţină opţiunea"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Doresc să se reţină opțiunea"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Puteți modifica ulterior în Setări &gt; Aplicații"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permiteți întotdeauna"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nu permiteți niciodată"</string>
@@ -1096,7 +1094,7 @@
     <string name="ime_action_previous" msgid="1443550039250105948">"Înapoi"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Executați"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Formaţi numărul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Creaţi contactul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Creați contactul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Următoarele aplicații solicită permisiunea de a accesa contul dvs. acum și în viitor."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Permiteți această solicitare?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Solicitare de acces"</string>
@@ -1121,7 +1119,7 @@
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Conectat(ă) la reţeaua VPN activată permanent"</string>
     <string name="vpn_lockdown_error" msgid="6009249814034708175">"Eroare de rețea VPN activată permanent"</string>
     <string name="vpn_lockdown_config" msgid="6415899150671537970">"Atingeți pentru a configura"</string>
-    <string name="upload_file" msgid="2897957172366730416">"Alegeţi un fişier"</string>
+    <string name="upload_file" msgid="2897957172366730416">"Alegeți un fișier"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Nu au fost găsite fișiere"</string>
     <string name="reset" msgid="2448168080964209908">"Resetaţi"</string>
     <string name="submit" msgid="1602335572089911941">"Trimiteți"</string>
@@ -1157,9 +1155,9 @@
     <string name="sync_really_delete" msgid="2572600103122596243">"Ștergeți elementele"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Anulați aceste ştergeri"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Nu trebuie să luați nicio măsură deocamdată"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"Alegeţi un cont"</string>
-    <string name="add_account_label" msgid="2935267344849993553">"Adăugaţi un cont"</string>
-    <string name="add_account_button_label" msgid="3611982894853435874">"Adăugaţi un cont"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Alegeți un cont"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Adăugați un cont"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Adăugați un cont"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"Creșteți"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"Reduceți"</string>
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Atingeți și țineți apăsat <xliff:g id="VALUE">%s</xliff:g>."</string>
@@ -1185,7 +1183,7 @@
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Schimbarea modului"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
-    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Alegeţi o aplicație"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Alegeți o aplicație"</string>
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nu s-a putut lansa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteți accesul pentru"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteți accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
@@ -1195,7 +1193,7 @@
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigaţi la ecranul de pornire"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigaţi în sus"</string>
-    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opţiuni"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opțiuni"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
     <string name="storage_internal" msgid="4891916833657929263">"Stocare internă"</string>
@@ -1204,7 +1202,7 @@
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unitate USB"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"Unitate USB <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Dsipozitiv de stocare USB"</string>
-    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Editaţi"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Editați"</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Avertisment de utiliz. a datelor"</string>
     <string name="data_usage_warning_body" msgid="2814673551471969954">"Atingeți pt. a afişa utiliz./set."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Ați atins limita de date 2G-3G"</string>
@@ -1234,7 +1232,7 @@
     <string name="sha256_fingerprint" msgid="4391271286477279263">"Amprentă SHA-256:"</string>
     <string name="sha1_fingerprint" msgid="7930330235269404581">"Amprentă SHA-1:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Afişaţi-le pe toate"</string>
-    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Alegeţi activitatea"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Alegeți activitatea"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Distribuiţi pentru"</string>
     <string name="sending" msgid="3245653681008218030">"Se trimite..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lansaţi browserul?"</string>
@@ -1293,18 +1291,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nume de utilizator sau parolă nevalide."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?\nAccesați "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Se verifică contul…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Ați efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a televizorului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, televizorul va reveni la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori.\n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Aţi efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Ați efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a televizorului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, televizorul va reveni la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Aţi efectuat <xliff:g id="NUMBER_0">%1$d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Ați efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a televizorului. Televizorul va reveni acum la setările prestabilite din fabrică."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Telefonul va fi acum resetat la setările prestabilite din fabrică."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereușite, vi se va solicita să deblocați televizorul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, vi se va solicita să deblocați televizorul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail.\n\n Încercați din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> (de) secunde."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminaţi"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ridicați volumul mai sus de nivelul recomandat?\n\nAscultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 3099237..8a64091 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -684,15 +684,15 @@
     <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">%d</xliff:g> раз неверно указали графический ключ. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали PIN-код. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google. \n\n Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Вы неправильно ввели графический ключ несколько раз (<xliff:g id="NUMBER_0">%d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%d</xliff:g>. После этого вам будет предложено разблокировать телевизор с помощью аккаунта Google.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google. \n\n Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать планшетный ПК. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Вы неправильно ввели графический ключ несколько раз (<xliff:g id="NUMBER_0">%d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%d</xliff:g>. После этого настройки телевизора будут сброшены, а все пользовательские данные – удалены."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать телефон. После <xliff:g id="NUMBER_1">%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">"Вы <xliff:g id="NUMBER_0">%1$d</xliff:g> раз неверно указали PIN-код. \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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Вы <xliff:g id="NUMBER">%d</xliff:g> раз не смогли разблокировать планшетный ПК. Будут восстановлены заводские настройки."</string>
     <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>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"слово"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ссылка"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"строка"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Не удалось провести стандартный тест"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Действие FACTORY_TEST поддерживается только для пакетов, установленных в /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Пакет, обеспечивающий действие FACTORY_TEST, не найден."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Неверное имя пользователя или пароль."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Забыли имя пользователя или пароль?\nПерейдите на страницу "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Проверка данных…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали PIN-код. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль.\n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ.\n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать планшетный ПК. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Вы неправильно ввели графический ключ несколько раз (<xliff:g id="NUMBER_0">%d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%d</xliff:g>. После этого настройки телевизора будут сброшены, а все пользовательские данные – удалены."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать телефон. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы <xliff:g id="NUMBER_0">%1$d</xliff:g> раз неверно указали PIN-код. \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_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">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google.\n\nПовтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Вы неправильно ввели графический ключ несколько раз (<xliff:g id="NUMBER_0">%d</xliff:g>). Осталось попыток: <xliff:g id="NUMBER_1">%d</xliff:g>. После этого вам будет предложено разблокировать телевизор с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google.\n\nПовтор через <xliff:g id="NUMBER_2">%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> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google.\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> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google.\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>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 35c1b90..c6f0d08 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ඔබ මුරපදය වාර <xliff:g id="NUMBER_0">%d</xliff:g> ක් වැරදියට ටයිප්කොට ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> කින් නැවත උත්සහ කරන්න."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ Google පුරනය වීම් භාවිතයෙන් ඔබගේ ටැබ්ලටය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> පසුව නැවත උත්සහ කරන්න."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ඔබ ඔබගේ අගුළු හැරීමේ මෝස්තරය <xliff:g id="NUMBER_0">%d</xliff:g> වරක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, ඔබට Google පුරනය භාවිතයෙන් ඔබගේ රූපවාහිනිය අගුළු හැරීමට සිදු වනු ඇත.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> කින් පසුව නැවත උත්සාහ කරන්න."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ Google පුරනය වීම භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසනු ඇත.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> පසුව නැවත උත්සහ කරන්න."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, ටැබ්ලටය කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ඔබ රූපවාහිනිය අගුළු හැරීමට <xliff:g id="NUMBER_0">%d</xliff:g> වරක් වැරදිව උත්සාහ කර ඇත. තවත් වැරදි උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කට පසුව, රූපවාහිනිය කර්මාන්තශාලා සුපුරුද්දට නැවත සකස් කෙරෙනු ඇති අතර, සියලුම පරිශීලක දත්ත නැති වී යනු ඇත."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ටැබ්ලටයේ අගුළු ඇරීමට ඔබ වැරදි ප්‍රයත්න <xliff:g id="NUMBER">%d</xliff:g> වාරයක් ගෙන ඇත. දැන් ටැබ්ලටය කර්මාන්තශාලා සුපුරුද්ද වෙත යළි පිහිටුවීම කෙරේ."</string>
     <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>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"වචනය"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"සබැඳිය"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"රේඛාව"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"කර්මාන්ත ශාලා පරීක්ෂණය අසාර්ථකයි"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ක්‍රියාව /system/app හි ස්ථාපිත පැකේජ සඳහා පමණක් සහය දක්වයි."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST ක්‍රියාව ලබාදෙන පැකේජයක් සොයාගත නොහැකි විය."</string>
@@ -1287,18 +1285,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"වලංගු නොවන පරිශීලක නාමයක් හෝ මුරපදයක්."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ඔබගේ පරිශීලක නාමය හෝ මුරපදය අමතකද?\n "<b>"google.com/accounts/recovery"</b>" වෙත යන්න."</string>
     <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">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ මුරපදය ඔබ වැරදියට ටයිප් කර ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ට පසුව නැවත උත්සහ කරන්න."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ඔබ <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ඔබ රූපවාහිනිය අගුළු හැරීමට <xliff:g id="NUMBER_0">%d</xliff:g> වරක් වැරදිව උත්සාහ කර ඇත. තවත් වැරදි උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කට පසුව, රූපවාහිනිය කර්මාන්තශාලා සුපුරුද්දට නැවත සකස් කෙරෙනු ඇති අතර, සියලුම පරිශීලක දත්ත නැති වී යනු ඇත."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, දුරකථනය කර්මාන්ත ශාලාවේ සුපුරුද්දට යළි පිහිටුවන අතර සියලුම පරිශීලක දත්ත නැති වී යයි."</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_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">%d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> කින් උත්සාහ කරන්න."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ඔබ ඔබගේ අගුළු හැරීමේ මෝස්තරය <xliff:g id="NUMBER_0">%d</xliff:g> වරක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, ඔබට ඊ-තැපැල් ගිණුමක් භාවිතයෙන් ඔබගේ රූපවාහිනිය අගුළු හැරීමට සිදු වනු ඇත.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> කින් පසුව නැවත උත්සාහ කරන්න."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 7fe6daf..0ecb92d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -684,15 +684,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Prečítajte si Príručku používateľa alebo kontaktujte podporu zákazníka."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karta je uzamknutá."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Prebieha odomykanie SIM karty..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších neúspešných pokusoch (<xliff:g id="NUMBER_1">%d</xliff:g>) budete vyzvaní odomknúť tablet pomocou prihlasovacích údajov služby Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Vzor na odomknutie ste nesprávne nakreslili <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%d</xliff:g>) sa zobrazí výzva na odomknutie vášho televízora pomocou prihlásenia Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou prihlasovacích údajov Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Televízor ste sa pokúsili nesprávne odomknúť <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%d</xliff:g>) sa obnovia výrobné nastavenia televízora a prídete o všetky údaje používateľa."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších neúspešných pokusoch (<xliff:g id="NUMBER_1">%2$d</xliff:g>) budete vyzvaní odomknúť tablet pomocou prihlasovacích údajov služby Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Vzor na odomknutie ste nesprávne nakreslili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) sa zobrazí výzva na odomknutie vášho televízora pomocou prihlásenia Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou prihlasovacích údajov Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Televízor ste sa pokúsili nesprávne odomknúť <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) sa obnovia výrobné nastavenia televízora a prídete o všetky údaje používateľa."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V tablete sa teraz obnovia predvolené výrobné nastavenia."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Televízor ste sa pokúsili nesprávne odomknúť <xliff:g id="NUMBER">%d</xliff:g>-krát. Teraz v ňom budú obnovené výrobné nastavenia."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V telefóne sa teraz obnovia predvolené výrobné nastavenia."</string>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"slovo"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"odkaz"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"riadok"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Továrenský test zlyhal"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Test FACTORY_TEST je možné uskutočniť iba pri balíčkoch nainštalovaných v priečinku /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nebol nájdený žiadny balíček umožňujúci test FACTORY_TEST."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné používateľské meno alebo heslo."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zabudli ste svoje používateľské meno alebo heslo?\n Navštívte stránky "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Prebieha kontrola účtu..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Televízor ste sa pokúsili nesprávne odomknúť <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%d</xliff:g>) sa obnovia výrobné nastavenia televízora a prídete o všetky údaje používateľa."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Televízor ste sa pokúsili nesprávne odomknúť <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) sa obnovia výrobné nastavenia televízora a prídete o všetky údaje používateľa."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené výrobné nastavenia a všetky používateľské údaje budú stratené."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V tablete sa teraz obnovia predvolené výrobné nastavenia."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Televízor ste sa pokúsili nesprávne odomknúť <xliff:g id="NUMBER">%d</xliff:g>-krát. Teraz sa v ňom obnovia výrobné nastavenia."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V telefóne sa teraz obnovia predvolené výrobné nastavenia."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Vzor na odomknutie ste nakreslili nesprávne <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%d</xliff:g>) sa zobrazí výzva na odomknutie televízora pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%2$d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Vzor na odomknutie ste nakreslili nesprávne <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát. Po ďalších neúspešných pokusoch (počet: <xliff:g id="NUMBER_1">%2$d</xliff:g>) sa zobrazí výzva na odomknutie televízora pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrániť"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Zvýšiť hlasitosť nad odporúčanú úroveň?\n\nDlhodobé počúvanie pri vysokej hlasitosti môže poškodiť váš sluch."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 3684d5b..a5c1013 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -684,15 +684,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Preberite uporabniški priročnik ali se obrnite na oddelek za skrb za stranke."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kartica SIM je zaklenjena."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odklepanje kartice SIM ..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete tablični računalnik z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"<xliff:g id="NUMBER_0">%d</xliff:g>-krat ste nepravilno narisali vzorec za odklepanje. Če vam ne uspe še <xliff:g id="NUMBER_1">%d</xliff:g>-krat, boste pozvani k odklepanju televizorja z geslom za Google.\n\n Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat nepravilno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve, vsi uporabniški podatki pa bodo izbrisani."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"<xliff:g id="NUMBER_0">%d</xliff:g>-krat ste nepravilno poskusili odkleniti televizor. Če vam ne uspe še <xliff:g id="NUMBER_1">%d</xliff:g>-krat, bo televizor ponastavljen na tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat nepravilno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve, vsi uporabniški podatki pa bodo izgubljeni."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Geslo ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete tablični računalnik z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krat ste nepravilno narisali vzorec za odklepanje. Če vam ne uspe še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani k odklepanju televizorja z geslom za Google.\n\n Poskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat nepravilno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve, vsi uporabniški podatki pa bodo izbrisani."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krat ste nepravilno poskusili odkleniti televizor. Če vam ne uspe še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo televizor ponastavljen na tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon ste poskusili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat nepravilno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve, vsi uporabniški podatki pa bodo izgubljeni."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablični računalnik ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat nepravilno odkleniti, zato bo zdaj ponastavljen na privzete tovarniške nastavitve."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"<xliff:g id="NUMBER">%d</xliff:g>-krat ste nepravilno poskusili odkleniti televizor. Televizor bo ponastavljen na tovarniške nastavitve."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Telefon ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat nepravilno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"beseda"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"povezava"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"vrstica"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Tovarniški preskus ni uspel"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Dejanje FACTORY_TEST je podprto le za pakete, nameščene v razdelku /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Ni bilo najdenega paketa, ki omogoča dejanje FACTORY_TEST."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neveljavno uporabniško ime ali geslo."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ali ste pozabili uporabniško ime ali geslo?\nObiščite "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Preverjanje računa ..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%d</xliff:g>-krat ste nepravilno poskusili odkleniti televizor. Če vam ne uspe še <xliff:g id="NUMBER_1">%d</xliff:g>-krat, bo televizor ponastavljen na tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefon ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Geslo ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krat ste nepravilno poskusili odkleniti televizor. Če vam ne uspe še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, bo televizor ponastavljen na tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefon ste poskusili <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablični računalnik ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"<xliff:g id="NUMBER">%d</xliff:g>-krat ste nepravilno poskusili odkleniti televizor. Televizor bo ponastavljen na tovarniške nastavitve."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"<xliff:g id="NUMBER_0">%d</xliff:g>-krat ste nepravilno narisali vzorec za odklepanje. Če vam ne uspe še <xliff:g id="NUMBER_1">%d</xliff:g>-krat, boste pozvani k odklepanju televizorja z e-poštnim računom.\n\n Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-krat ste nepravilno narisali vzorec za odklepanje. Če vam ne uspe še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani k odklepanju televizorja z e-poštnim računom.\n\n Poskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%2$d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrani"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ali želite povečati glasnost nad priporočeno raven?\n\nDolgotrajno poslušanje pri veliki glasnosti lahko poškoduje sluh."</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 88e0f1a..82f8b3b 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Shiko \"Manualin e përdorimit\" ose kontakto \"Kujdesin ndaj klientit\"."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Karta SIM është e kyçur."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Po shkyç kartën SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për të vizatuar motivin tënd.\n\nProvo sërish për <xliff:g id="NUMBER_1">%d</xliff:g> sekonda."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"E ke shkruar <xliff:g id="NUMBER_0">%d</xliff:g> herë gabim fjalëkalimin. \n\nProvo sërish për <xliff:g id="NUMBER_1">%d</xliff:g> sekonda."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"E ke shkruar <xliff:g id="NUMBER_0">%d</xliff:g> herë gabimisht PIN-in tënd.\n\nProvo sërish për <xliff:g id="NUMBER_1">%d</xliff:g> sekonda."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Ke vizatuar <xliff:g id="NUMBER_0">%d</xliff:g> herë gabimisht motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, do të të kërkohet ta shkyçësh tabletin duke përdorur identifikimin në Google.\n\n Provo sërish për <xliff:g id="NUMBER_2">%d</xliff:g> sekonda."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"E ke vizatuar <xliff:g id="NUMBER_0">%d</xliff:g> herë gabimisht motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme do të të kërkohet ta shkyçësh televizorin duke përdorur identifikimin në Google.\n\n Provo sërish për <xliff:g id="NUMBER_2">%d</xliff:g> sekonda."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ke vizatuar <xliff:g id="NUMBER_0">%d</xliff:g> herë gabimisht motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, do të të kërkohet ta shkyçësh telefonin duke përdorur identifikimin në Google.\n\n Provo sërish për <xliff:g id="NUMBER_2">%d</xliff:g> sekonda."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për ta shkyçur tabletin. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, tableti do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për ta shkyçur televizorin. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, televizori do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, telefoni do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për të vizatuar motivin tënd.\n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"E ke shkruar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabim fjalëkalimin. \n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"E ke shkruar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht PIN-in tënd.\n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të kërkohet ta shkyçësh tabletin duke përdorur identifikimin në Google.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"E ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme do të të kërkohet ta shkyçësh televizorin duke përdorur identifikimin në Google.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të kërkohet ta shkyçësh telefonin duke përdorur identifikimin në Google.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur tabletin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, tableti do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur televizorin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, televizori do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur telefonin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, telefoni do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur tabletin tënd. Tableti tani do të rivendoset në gjendje fabrike."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë ta shkyçësh pa sukses televizorin tënd. Televizori do të rivendoset tani si në gjendjen e fabrikës."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë ta shkyçësh pa sukses telefonin tënd. Telefoni do të rivendoset tani si në gjendjen e fabrikës."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"fjalë"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"lidhje"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linjë"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Testimi i fabrikës dështoi"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Veprimi i TESTIT_TË_FABRIKËS mbështetet vetëm për paketat e instaluara në /sistem/apl."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nuk u gjet asnjë paketë që siguron veprimin e TESTIT_TË_FABRIKËS."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Emër përdoruesi ose fjalëkalim i pavlefshëm."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Harrove emrin e përdoruesit apo fjalëkalimin?\nVizito "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Po kontrollon llogarinë…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"E ke shkruar <xliff:g id="NUMBER_0">%d</xliff:g> herë gabimisht PIN-in tënd.\n\n Provo sërish për <xliff:g id="NUMBER_1">%d</xliff:g> sekonda."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"E ke shkruar <xliff:g id="NUMBER_0">%d</xliff:g> herë gabimisht fjalëkalimin.\n\nProvo sërish për <xliff:g id="NUMBER_1">%d</xliff:g> sekonda."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për të vizatuar motivin tënd. \n\nProvo sërish për <xliff:g id="NUMBER_1">%d</xliff:g> sekonda."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për ta shkyçur tabletin tënd. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, tableti do të rivendoset në gjendje fabrike dhe të gjitha të dhënat e përdoruesit do të humbasin."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për ta shkyçur televizorin. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, televizori do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Ke tentuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses për ta shkyçur telefonin tënd. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, telefoni do të rivendoset në gjendje fabrike dhe të gjitha të dhënat e përdoruesit do të humbasin."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"E ke shkruar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht PIN-in tënd.\n\n Provo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"E ke shkruar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht fjalëkalimin.\n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për të vizatuar motivin tënd. \n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur tabletin tënd. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, tableti do të rivendoset në gjendje fabrike dhe të gjitha të dhënat e përdoruesit do të humbasin."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur televizorin. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, televizori do të rivendoset në gjendjen e fabrikës dhe të gjitha të dhënat e përdoruesit do të humben."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për ta shkyçur telefonin tënd. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, telefoni do të rivendoset në gjendje fabrike dhe të gjitha të dhënat e përdoruesit do të humbasin."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur tabletin tënd. Tableti tani do të rivendoset në gjendje fabrike."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë ta shkyçësh pa sukses televizorin tënd. Televizori do të rivendoset tani si në gjendjen e fabrikës."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë ta shkyçësh pa sukses telefonin tënd. Telefoni do të rivendoset tani si në gjendjen e fabrikës."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"E ke vizatuar gabimisht motivin tënd të shkyçjes <xliff:g id="NUMBER_0">%d</xliff:g> herë. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme do të të kërkohet ta shkyçësh tabletin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%d</xliff:g> sekonda."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Ke vizatuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses motivin tënd. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh televizorin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%d</xliff:g> sekonda."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ke vizatuar <xliff:g id="NUMBER_0">%d</xliff:g> herë pa sukses motivin tënd. Pas <xliff:g id="NUMBER_1">%d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh telefonin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%d</xliff:g> sekonda."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"E ke vizatuar gabimisht motivin tënd të shkyçjes <xliff:g id="NUMBER_0">%1$d</xliff:g> herë. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme do të të kërkohet ta shkyçësh tabletin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh televizorin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh telefonin duke përdorur një llogari mail-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Hiq"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Të ngrihet volumi mbi nivelin e rekomanduar?\n\nDëgjimi me volum të lartë për periudha të gjata mund të dëmtojë dëgjimin."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 019af38..bab8944 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -683,15 +683,15 @@
     <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">%d</xliff:g> пута сте неправилно нацртали шаблон за откључавање. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте погрешно унели лозинку. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте погрешно унели PIN. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу података за пријављивање на Google.\n\n Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Неисправно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја од вас ће бити затражено да откључате ТВ помоћу података за пријављивање на Google.\n\n Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу података за пријављивање на Google.\n\n Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Неправилно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%d</xliff:g>) таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Покушали сте да откључате ТВ нетачно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја ТВ ће бити ресетован на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%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">"<xliff:g id="NUMBER_0">%1$d</xliff:g> пута сте погрешно унели PIN. \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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Неисправно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
     <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>
@@ -743,8 +743,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"реч"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"веза"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ред"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Фабричко тестирање није успело"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Радња FACTORY_TEST је подржана само за пакете инсталиране у директоријуму /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Није пронађен ниједан пакет који обезбеђује радњу FACTORY_TEST."</string>
@@ -1293,18 +1291,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Неважеће корисничко име или лозинка."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Заборавили сте корисничко име или лозинку?\nПосетите адресу "<b>"google.com/accounts/recovery"</b>"."</string>
     <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">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Унели сте нетачну лозинку <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Покушали сте да откључате таблет нетачно <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја таблет ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Покушали сте да откључате ТВ нетачно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја ТВ ће бити ресетован на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Покушали сте да откључате телефон нетачно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја телефон ће бити ресетован на фабричка подешавања и сви кориснички подаци ће бити изгубљени."</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_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">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште.\n\nПокушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Неисправно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате ТВ помоћу налога е-поште.\n\n Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Нацртали сте шаблон за откључавање нетачно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште.\n\nПокушајте поново за <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4a25b9d..3909c6b 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Se användarhandboken eller kontakta kundtjänst."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortet är låst."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Låser upp SIM-kort…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp surfplattan med din Google-inloggning.\n\n Försök igen om  <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök blir du ombedd att låsa upp TV:n genom att logga in på Google.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp mobilen med uppgifterna som du använder när du loggar in på Google.\n\n Försök igen om  <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök till kommer surfplattan att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök kommer TV:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök till kommer mobilen att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> försök till ombeds du att låsa upp surfplattan med din Google-inloggning.\n\n Försök igen om  <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök blir du ombedd att låsa upp TV:n genom att logga in på Google.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> försök till ombeds du att låsa upp mobilen med uppgifterna som du använder när du loggar in på Google.\n\n Försök igen om  <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök till kommer surfplattan att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök kommer TV:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök till kommer mobilen att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER">%d</xliff:g> gånger. TV:n kommer nu att återställas till standardinställningarna."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs nu till fabriksinställningarna."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"ord"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"länk"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"rad"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Det gick fel vid fabrikstestet"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Åtgärden FACTORY_TEST stöds endast för paket som har installerats i /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Vi hittade inget paket som erbjuder åtgärden FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ogiltigt användarnamn eller lösenord."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glömt ditt användarnamn eller lösenord?\nBesök "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontot kontrolleras …"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs surfplattan till fabriksinställningarna. Du förlorar då alla användardata."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök kommer TV:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs mobilen till fabriksinställningarna. Du förlorar då alla användardata."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök återställs surfplattan till fabriksinställningarna. Du förlorar då alla användardata."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök kommer TV:n att återställas till standardinställningarna och alla användaruppgifter kommer att gå förlorade."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök återställs mobilen till fabriksinställningarna. Du förlorar då alla användardata."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Du har misslyckats med att låsa upp TV:n <xliff:g id="NUMBER">%d</xliff:g> gånger. TV:n kommer nu att återställas till standardinställningarna."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs nu till fabriksinställningarna."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök blir du ombedd att låsa upp TV:n via ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Du har ritat fel mönster för upplåsning <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> misslyckade försök blir du ombedd att låsa upp TV:n via ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ta bort"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Vill du höja volymen över den rekommenderade nivån?\n\nAtt lyssna med stark volym långa stunder åt gången kan skada hörseln."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ef08448..c9cdd8d 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -684,15 +684,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Angalia Mwongozo wa Mtumiaji au wasiliana na Huduma ya Wateja."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kadi imefungwa."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Inafungua SIM kadi..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Umekosea katika kuchora ruwaza yako ya kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena kwa sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Umekosea mara <xliff:g id="NUMBER_0">%d</xliff:g> katika kuingiza nenosiri lako. \n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Umekosea katika kuingiza PIN yako mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaulizwa kufungua kompyuta yako ndogo kwa kuingia kwa Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Umekosea kuchora mchoro wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Ukikosea majaribio mengine <xliff:g id="NUMBER_1">%d</xliff:g>, utaombwa ufungue runinga yako ukitumia Google.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaulizwa kufungua simu kupitia kuingia Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya zaidi ya <xliff:g id="NUMBER_1">%d</xliff:g> majaribio yasiyofanikiwa, kompyuta ndogo itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER_0">%d</xliff:g>. Ukikosea majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi, runinga itarejeshwa katika hali iliyotoka nayo kiwandani na data yote ya watumiaji itafutwa."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofanikiwa, simu itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Umekosea katika kuchora ruwaza yako ya kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena kwa sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Umekosea mara <xliff:g id="NUMBER_0">%1$d</xliff:g> katika kuingiza nenosiri lako. \n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Umekosea katika kuingiza PIN yako mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> bila kufaulu, utaulizwa kufungua kompyuta yako ndogo kwa kuingia kwa Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Umekosea kuchora mchoro wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea majaribio mengine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa ufungue runinga yako ukitumia Google.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> yasiyofaulu, utaulizwa kufungua simu kupitia kuingia Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya zaidi ya <xliff:g id="NUMBER_1">%2$d</xliff:g> majaribio yasiyofanikiwa, kompyuta ndogo itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi, runinga itarejeshwa katika hali iliyotoka nayo kiwandani na data yote ya watumiaji itafutwa."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi yasiyofanikiwa, simu itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Kompyuta ndogo haitaweza kuwekwa upya kwa kiwanda chaguo-msingi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa runinga itarejeshwa katika mipangilio iliyotoka nayo kiwandani."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Kompyuta ndogo haitaweza kuwekwa upya kwa kiwanda chaguo-msingi."</string>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"neno"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"kiungo"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"mstari"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Jaribio la kiwanda limeshindikana"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Tendo la JARIBIO_LA KIWANDA  linahimiliwa tu kwa furushi zilizosakinishwa katika /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Hakuna furushi lililopatikana ambalo linatoa tendo la JARIBIO_LA KIWANDA."</string>
@@ -1287,18 +1285,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Jina la mtumiaji au nenosiri batili."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Je, umesahau jina lako la mtumiaji au nenosiri?\nTembela "<b>"Bgoogle.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Inakagua akaunti…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Umechora ruwaza yako ya kufunga kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani data yote ya mtumiaji itapotea."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER_0">%d</xliff:g>. Ukikosea majaribio mengine <xliff:g id="NUMBER_1">%d</xliff:g>, runinga itarejeshwa katika hali iliyotoka nayo kiwandani na data yote ya watumiaji itafutwa."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, simu itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani na data yote ya mtumiaji itapotea."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Umechora ruwaza yako ya kufunga kwa makosa mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi yasiyofaulu, kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani data yote ya mtumiaji itapotea."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea majaribio mengine <xliff:g id="NUMBER_1">%2$d</xliff:g>, runinga itarejeshwa katika hali iliyotoka nayo kiwandani na data yote ya watumiaji itafutwa."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi yasiyofaulu, simu itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani na data yote ya mtumiaji itapotea."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Umekosea majaribio ya kufungua runinga mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa runinga itarejeshwa katika hali iliyotoka nayo kiwandani."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa simu  itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Umekosea kuchora mchoro wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Ukikosea majaribio mengine <xliff:g id="NUMBER_1">%d</xliff:g>, utaombwa ufungue runinga yako ukitumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Umekosea kuchora mchoro wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea majaribio mengine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa ufungue runinga yako ukitumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <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">"Ondoa"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ungependa kupandisha sauti zaidi ya kiwango kinachopendekezwa?\n\nKusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index efa5304..67b85583 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"பயனர் கையேட்டைப் பார்க்கவும் அல்லது வாடிக்கையாளர் சேவையைத் தொடர்புகொள்ளவும்."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"சிம் கார்டு பூட்டப்பட்டுள்ளது."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"சிம் கார்டைத் திறக்கிறது..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"உங்கள் கடவுச்சொல்லை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"உங்கள் பின்னை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை தவறாக வரைந்தால், உங்கள் Google உள்நுழைவைப் பயன்படுத்தி டேப்லெட்டைத் திறக்குமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை தவறாக வரைந்தால், Google உள்நுழைவைப் பயன்படுத்தி டிவியைத் திறக்கும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> வினாடிகள் கழித்து முயலவும்."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை தவறாக வரைந்தால், உங்கள் Google உள்நுழைவைப் பயன்படுத்தி மொபைலைத் திறக்குமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"டேப்லெட்டைத் தடைநீக்க <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, டேப்லெட்டானது ஆரம்ப இயல்புநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவும் இழக்கப்படும்."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"டிவியை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாகத் திறக்க முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை தவறாக முயற்சித்தால், டிவி ஆரம்பநிலைக்கு மீட்டமைக்கப்படுவதுடன், எல்லா பயனர் தரவும் அழிக்கப்படும்."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"தொலைபேசியைத் தடைநீக்க <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%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">"உங்கள் பின்னை <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"நீங்கள் டேப்லெட்டைத் தடைநீக்க <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். டேப்லெட் இப்போது ஆரம்ப இயல்புநிலைக்கு மீட்டமைக்கப்படும்."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"சொல்"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"இணைப்பு"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"வரி"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ஆரம்பச் சோதனையில் தோல்வி"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"/system/app இல் நிறுவப்பட்ட தொகுப்புகளுக்கு மட்டுமே FACTORY_TEST செயல் ஆதரிக்கப்படும்."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST செயலை வழங்கும் எந்தத் தொகுப்பும் கண்டறியப்படவில்லை."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"தவறான பயனர்பெயர் அல்லது கடவுச்சொல்."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"உங்கள் பயனர்பெயர் அல்லது கடவுச்சொல்லை மறந்துவிட்டீர்களா?\n"<b>"google.com/accounts/recovery"</b>" ஐப் பார்வையிடவும்."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"கணக்கைச் சரிபார்க்கிறது…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"உங்கள் பின்னை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"உங்கள் கடவுச்சொல்லை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். \n\n<xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகளில் மீண்டும் முயற்சிக்கவும்."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"டேப்லெட்டைத் திறக்க <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, டேப்லெட்டானது ஆரம்பநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவையும் இழப்பீர்கள்."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"டிவியை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாகத் திறக்க முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை தவறாக முயற்சித்தால், டிவி ஆரம்பநிலைக்கு மீட்டமைக்கப்படுவதுடன், எல்லா பயனர் தரவும் அழிக்கப்படும்."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"மொபைலைத் திறக்க <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு,மொபைலானது ஆரம்பநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவையும் இழப்பீர்கள்."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"உங்கள் பின்னை <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_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">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். மேலும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, மின்னஞ்சல் கணக்கைப் பயன்படுத்தி உங்கள் டேப்லெட்டைத் திறக்க கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> வினாடிகளில் மீண்டும் முயற்சிக்கவும்."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி டிவியைத் திறக்கும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> வினாடிகள் கழித்து முயலவும்."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். மேலும் <xliff:g id="NUMBER_1">%d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, மின்னஞ்சல் கணக்கைப் பயன்படுத்தி உங்கள் மொபைலைத் திறக்கக் கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 155c2dd..97789e1 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"వినియోగదారు గైడ్‌ను చూడండి లేదా కస్టమర్ కేర్‌ను సంప్రదించండి."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"సిమ్ కార్డు లాక్ చేయబడింది."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"సిమ్ కార్డు‌ను అన్‌లాక్ చేస్తోంది…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"మీరు మీ పాస్‌వర్డ్‌ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"మీరు మీ పిన్‌ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"మీరు మీ అన్‌లాక్ నమూనాని <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విజయవంతం కాని ప్రయత్నాల తర్వాత, మీరు మీ Google సైన్ఇన్‌ను ఉపయోగించి మీ టాబ్లెట్‌ను అన్‌లాక్ చేయడానికి అడగబడతారు.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీశారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు విఫలమైతే, మీరు మీ Google సైన్ ఇన్‌ను ఉపయోగించి మీ టీవీని అన్‌లాక్ చేయమని అడుగుతాము.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"మీరు మీ అన్‌లాక్ నమూనాని <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విజయవంతం కాని ప్రయత్నాల తర్వాత, మీరు మీ Google సైన్ఇన్‌ను ఉపయోగించి మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి అడగబడతారు.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"మీరు టాబ్లెట్‌ను అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా ప్రయత్నించారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> వైఫల్య ప్రయత్నాల తర్వాత, టాబ్లెట్ ఫ్యాక్టరీ డిఫాల్ట్‌కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోవడం సంభవిస్తుంది."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"మీరు టీవీని అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేశారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు విఫలమైతే, టీవీ ఫ్యాక్టరీ డిఫాల్ట్‌కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోతారు."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"మీరు ఫోన్‌ను అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా ప్రయత్నించారు. మరో <xliff:g id="NUMBER_1">%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">"మీరు మీ పిన్‌ను <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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"మీరు టాబ్లెట్‌ను అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు తప్పుగా ప్రయత్నించారు. టాబ్లెట్ ఇప్పుడు ఫ్యాక్టరీ డిఫాల్ట్‌కు రీసెట్ చేయబడుతుంది."</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"పదం"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"లింక్"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"పంక్తి"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"ఫ్యాక్టరీ పరీక్ష విఫలమైంది"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"/system/appలో ఇన్‌స్టాల్ చేయబడిన ప్యాకేజీల కోసం మాత్రమే FACTORY_TEST చర్యకు మద్దతు ఉంటుంది."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST చర్యను అందించే ప్యాకేజీ ఏదీ కనుగొనబడలేదు."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"చెల్లని వినియోగదారు పేరు లేదా పాస్‌వర్డ్."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"మీ వినియోగదారు పేరు లేదా పాస్‌వర్డ్‌ను మర్చిపోయారా?\n"<b>"google.com/accounts/recovery"</b>"ని సందర్శించండి."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"ఖాతాను తనిఖీ చేస్తోంది…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"మీరు మీ పిన్‌ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"మీరు మీ పాస్‌వర్డ్‌ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"మీరు టాబ్లెట్‌ను అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విఫల ప్రయత్నాల తర్వాత, టాబ్లెట్ ఫ్యాక్టరీ డిఫాల్ట్‌కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోవడం సంభవిస్తుంది."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"మీరు టీవీని అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు చెల్లని ప్రయత్నాలు చేశారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు విఫలమైతే, టీవీ ఫ్యాక్టరీ డిఫాల్ట్‌కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోతారు."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"మీరు ఫోన్‌ను అన్‌లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఫోన్ ఫ్యాక్టరీ డిఫాల్ట్‌కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోవడం సంభవిస్తుంది."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"మీరు మీ పిన్‌ను <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_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">%d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఇమెయిల్ ఖాతాను ఉపయోగించి మీ టాబ్లెట్‌ను అన్‌లాక్ చేయాల్సిందిగా మిమ్మల్ని అడుగుతారు.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీశారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు విఫలమైతే, ఇమెయిల్ ఖాతాను ఉపయోగించి మీ టీవీని అన్‌లాక్ చేయమని మిమ్మల్ని అడుగుతాము.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విఫల ప్రయత్నాల తర్వాత, ఇమెయిల్ ఖాతాను ఉపయోగించి మీ ఫోన్‌ను అన్‌లాక్ చేయాల్సిందిగా మిమ్మల్ని అడుగుతారు.\n\n <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 3d65203..013da3d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ดูคู่มือผู้ใช้หรือติดต่อศูนย์บริการลูกค้า"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"ซิมการ์ดถูกล็อก"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"กำลังปลดล็อกซิมการ์ด…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว\n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว\n\nลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"คุณพิมพ์ PIN ไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว\n\nลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้การลงชื่อเข้าใช้ Google\n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากวาดไม่ถูกต้องอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกทีวีโดยการลงชื่อเช้าใช้ Google\n\n โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้การลงชื่อเข้าใช้ Google\n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้องแล้ว <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากการพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลทั้งหมดของผู้ใช้จะหายไป"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"คุณพยายามปลดล็อกทีวีอย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากปลดล็อกไม่ถูกต้องอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ทีวีจะรีเซ็ตเป็นค่าเริ่มต้นจากโรงงาน และข้อมูลผู้ใช้ทั้งหมดจะหายไป"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้องแล้ว <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากการพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้องแล้ว <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ขณะนี้แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงาน"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"คำ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"ลิงก์"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"บรรทัด"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"การทดสอบจากโรงงานล้มเหลว"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"การทำงาน FACTORY_TEST ได้รับการสนับสนุนเฉพาะสำหรับแพ็คเก็จที่ติดตั้งใน /system/app เท่านั้น"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"ไม่พบแพ็กเกจที่มีการทำงาน FACTORY_TEST"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"หากลืมชื่อผู้ใช้หรือรหัสผ่าน\nโปรดไปที่ "<b>"google.com/accounts/recovery"</b></string>
     <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">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลผู้ใช้ทั้งหมดจะหายไป"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"คุณพยายามปลดล็อกทีวีอย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากปลดล็อกไม่ถูกต้องอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ทีวีจะรีเซ็ตเป็นค่าเริ่มต้นจากโรงงาน และข้อมูลผู้ใช้ทั้งหมดจะหายไป"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง โทรศัพท์จะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลผู้ใช้ทั้งหมดจะหายไป"</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_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">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากวาดไม่ถูกต้องอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกทีวีด้วยบัญชีอีเมล\n\n ลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 0587056..8c6c37d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Tingnan ang Gabay ng User o makipag-ugnay sa Pangangalaga sa Customer."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Naka-lock ang SIM card."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ina-unlock ang SIM card…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Mali mong naguhit ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Na-type mo nang mali ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Na-type mo nang mali ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Naiguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong tablet gamit ang iyong pag-sign-in sa Google.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Naiguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, sasabihan kang i-unlock ang iyong TV sa pamamagitan ng pag-sign in sa Google.\n\n Subukang muli sa <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Naguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong telepono gamit ang iyong pag-sign-in sa Google.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Mali mong tinangkang ma-unlock ang tablet nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang mga hindi matagumpay na pagtatangka, mare-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Mali nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses ang iyong pagtatangkang i-unlock ang TV. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, mare-reset sa default ng factory ang TV at mawawala ang lahat ng data ng user."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Mali mong tinangkang ma-unlock ang telepono nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang mga hindi matagumpay na pagtatangka, mare-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Mali mong naguhit ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Na-type mo nang mali ang iyong password nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Na-type mo nang mali ang iyong PIN nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Naiguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong tablet gamit ang iyong pag-sign-in sa Google.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Naiguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, sasabihan kang i-unlock ang iyong TV sa pamamagitan ng pag-sign in sa Google.\n\n Subukang muli sa <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Naguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong telepono gamit ang iyong pag-sign-in sa Google.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Mali mong tinangkang ma-unlock ang tablet nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang mga hindi matagumpay na pagtatangka, mare-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Mali nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses ang iyong pagtatangkang i-unlock ang TV. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, mare-reset sa default ng factory ang TV at mawawala ang lahat ng data ng user."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Mali mong tinangkang ma-unlock ang telepono nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang mga hindi matagumpay na pagtatangka, mare-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Mali mong tinangkang ma-unlock ang tablet nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Mare-reset na ngayon ang tablet sa factory default."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Mali nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses ang iyong pagtatangkang i-unlock ang TV. Mare-reset na ngayon ang TV sa default ng factory."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Mali mong tinangkang ma-unlock ang telepono nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Mare-reset na ang telepono sa factory default."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"salita"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"linya"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Nabigo ang factory na pagsubok"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Suportado lang ang pagkilos na FACTORY_TEST para sa mga package na naka-install sa /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Walang nakitang package na nagbibigay ng pagkilos na FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Di-wastong username o password."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nakalimutan ang iyong username o password?\nBisitahin ang "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Tinitingnan ang account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Na-type mo nang hindi tama ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tinangka mo sa hindi tamang paraan na i-unlock ang tabelt nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Mali nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses ang iyong pagtatangkang i-unlock ang TV. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, mare-reset sa default ng factory ang TV at mawawala ang lahat ng data ng user."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Na-type mo nang hindi tama ang iyong PIN nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tinangka mo sa hindi tamang paraan na i-unlock ang tabelt nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Mali nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses ang iyong pagtatangkang i-unlock ang TV. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, mare-reset sa default ng factory ang TV at mawawala ang lahat ng data ng user."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tinangka mo sa hindi tamang paraan na i-unlock ang tablet nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang tablet sa factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Mali nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses ang iyong pagtatangkang i-unlock ang TV. Mare-reset na ngayon ang TV sa default ng factory."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang telepono sa factory default."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Naiguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, sasabihan kang i-unlock ang iyong TV gamit ang isang email account.\n\n Subukang muli sa <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Naiguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, sasabihan kang i-unlock ang iyong TV gamit ang isang email account.\n\n Subukang muli sa <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alisin"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Lakasan ang volume nang lagpas sa inirerekomendang antas?\n\nMaaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index daaee4e..20f6191 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Kullanıcı Rehberi\'ne bakın veya Müşteri Hizmetleri\'ne başvurun."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kart kilitli."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM kart kilidi açılıyor…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi, Google oturum açma bilgilerinizi kullanarak açmanız istenir.\n\n<xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez hatalı bir şekilde çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız deneme daha yaparsanız TV\'nizin kilidini Google oturum açma bilgilerinizi kullanarak açmanız istenecektir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu Google oturum açma bilgilerinizi kullanarak açmanız istenir.\n\n Lütfen <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılanına sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"TV\'nizin kilidini <xliff:g id="NUMBER_0">%d</xliff:g> kez hatalı bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız deneme daha yaparsanız TV\'niz fabrika ayalarına sıfırlanacak ve tüm kullanıcı verileri kaybolacaktır."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefonun kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılanına sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrenizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodunuzu <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra, tabletinizi, Google oturum açma bilgilerinizi kullanarak açmanız istenir.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız TV\'nizin kilidini Google oturum açma bilgilerinizi kullanarak açmanız istenecektir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra telefonunuzu Google oturum açma bilgilerinizi kullanarak açmanız istenir.\n\n Lütfen <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%2$d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılanına sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"TV\'nizin kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız TV\'niz fabrika ayalarına sıfırlanacak ve tüm kullanıcı verileri kaybolacaktır."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefonun kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%2$d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılanına sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Tablet şimdi fabrika varsayılanına sıfırlanacak."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"TV\'nizin kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmaya çalıştınız. TV\'niz şimdi fabrika ayarlarına sıfırlanacaktır."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Telefon kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Telefon şimdi fabrika varsayılanına sıfırlanacak."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"kelime"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"bağlantı"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"satır"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabrika testi yapılamadı"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST işlemi yalnızca /system/app dizinine yüklenmiş paketler için desteklenir."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST işlemini sağlayan hiçbir paket bulunamadı."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Geçersiz kullanıcı adı veya şifre."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?\n"<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesap denetleniyor…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"TV\'nizin kilidini <xliff:g id="NUMBER_0">%d</xliff:g> kez hatalı bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız deneme daha yaparsanız TV\'niz fabrika ayalarına sıfırlanacak ve tüm kullanıcı verileri kaybolacaktır."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefonun kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrenizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%2$d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"TV\'nizin kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız TV\'niz fabrika ayalarına sıfırlanacak ve tüm kullanıcı verileri kaybolacaktır."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefonun kilidini <xliff:g id="NUMBER_0">%1$d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%2$d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Tablet şimdi fabrika varsayılanına sıfırlanacak."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"TV\'nizin kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmaya çalıştınız. TV\'niz şimdi fabrika ayarlarına sıfırlanacaktır."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Telefon şimdi fabrika varsayılanına sıfırlanacak."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız deneme daha yaparsanız TV\'nizin kilidini bir e-posta hesabı kullanarak açmanız istenecektir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız TV\'nizin kilidini bir e-posta hesabı kullanarak açmanız istenecektir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Kaldır"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ses seviyesi önerilen düzeyin üzerine yükseltilsin mi?\n\nUzun süre yüksek ses seviyesinde dinlemek işitme duyunuza zarar verebilir."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index d41dba5..871153f 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -684,15 +684,15 @@
     <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">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>.\n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN-код неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>.\n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Ваш планшетний ПК потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%d</xliff:g>.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Ви неправильно намалювали ключ розблокування стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телевізор за допомогою входу в Google.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> c."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Ваш телефон потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%d</xliff:g>.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Кількість невдалих спроб розблокувати пристрій: <xliff:g id="NUMBER_0">%d</xliff:g>. Налаштування пристрою буде змінено на заводські за умовчанням, а всі дані користувача буде втрачено після ще стількох невдалих спроб: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Кількість невдалих спроб розблокувати телевізор: <xliff:g id="NUMBER_0">%d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі всі налаштування телевізора буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%d</xliff:g>. Налаштування телефону буде змінено на заводські за умовчанням, а всі дані користувача буде втрачено після ще стількох невдалих спроб: <xliff:g id="NUMBER_1">%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>. Ваш планшетний ПК потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>.\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> c."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ваш телефон потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>.\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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Кількість невдалих спроб розблокувати пристрій: <xliff:g id="NUMBER">%d</xliff:g>. Налаштування пристрою буде змінено на заводські за умовчанням."</string>
     <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>
@@ -744,8 +744,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"слово"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"посилання"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"рядок"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Помилка завод. тесту"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Дія FACTORY_TEST підтримується лише для пакетів, установлених у /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Не було знайдено жодного пакета, який надає дію FACTORY_TEST."</string>
@@ -1301,18 +1299,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Недійсне ім’я користувача чи пароль."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Не пам’ятаєте ім’я користувача чи пароль?\nВідвідайте сторінку "<b>"google.com/accounts/recovery"</b>"."</string>
     <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">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Кількість невдалих спроб розблокувати планшетний ПК: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі налаштування планшетного ПК буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Кількість невдалих спроб розблокувати телевізор: <xliff:g id="NUMBER_0">%d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі всі налаштування телевізора буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі налаштування телефону буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</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_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">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Ви неправильно намалювали ключ розблокування стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телевізор за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> c."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%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> c."</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>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index e37f03b..175a840 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"آپ نے اپنا پاس ورڈ <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"‏آپ نے <xliff:g id="NUMBER_0">%d</xliff:g> بار اپنا PIN غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"‏آپ نے اپنے غیر مقفل کرنے کے پیٹرن کو <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے اپنے Google سائن ان کا استعمال کرکے اپنے ٹیبلٹ کو غیر مقفل کرنے کیلئے کہا جائے گا۔ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> سیکنڈز بعد دوبارہ کوشش کریں۔"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"‏آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے اپنا Google سائن ان استعمال کرکے اپنا TV غیر مقفل کرنے کو کہا جائے گا۔‎\n\n <xliff:g id="NUMBER_2">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"‏آپ نے اپنے غیر مقفل کرنے کے پیٹرن کو <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے اپنے Google سائن ان کا استعمال کرکے اپنے فون کو غیر مقفل کرنے کیلئے کہا جائے گا۔ \n\n <xliff:g id="NUMBER_2">%d</xliff:g> سیکنڈز بعد دوبارہ کوشش کریں۔"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"آپ نے ٹیبلیٹ کو <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقہ سے غیر مقفل کرنے کی کوشش کی ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، ٹیبلیٹ کو فیکٹری ڈیفالٹ پر ری سیٹ کر دیا جائے گیا اور صارف کا سبھی ڈیٹا ضائع ہو جائے گا۔"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"‏آپ نے TV کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے کوششیں کی ہیں۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، TV فیکٹری ڈیفالٹ پر ری سیٹ ہو جائے گا اور صارف کا سبھی ڈیٹا ضائع ہو جائے گا۔"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"آپ نے فون کو <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقہ سے غیر مقفل کرنے کی کوشش کی ہے۔ <xliff:g id="NUMBER_1">%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">"‏آپ نے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اپنا PIN غلط طریقے سے ٹائپ کیا ہے۔ \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 سائن ان استعمال کرکے اپنا TV غیر مقفل کرنے کو کہا جائے گا۔‎\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">"‏آپ نے TV کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوششیں کی ہیں۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، TV فیکٹری ڈیفالٹ پر ری سیٹ ہو جائے گا اور صارف کا سبھی ڈیٹا ضائع ہو جائے گا۔"</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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"آپ نے ٹیبلیٹ کو <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقہ سے غیر مقفل کرنے کی کوشش کی ہے۔ ٹیبلیٹ کو اب فیکٹری ڈیفالٹ پر ری سیٹ کر دیا جائے گیا۔"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"‏آپ نے TV کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ TV اب فیکٹری ڈیفالٹ پر ری سیٹ ہو جائے گا۔"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"آپ نے فون کو <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقہ سے غیر مقفل کرنے کی کوشش کی ہے۔ فون کو اب فیکٹری ڈیفالٹ پر ری سیٹ کر دیا جائے گیا۔"</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"لفظ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"لنک"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"لکیر"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"فیکٹری ٹیسٹ ناکام رہا"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"‏FACTORY_TEST کارروائی صرف ‎/system/app میں انسٹال کردہ پیکیجز کیلئے تعاون یافتہ ہے۔"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"‏ایسا کوئی پیکیج نہیں ملا، جو FACTORY_TEST کارروائی فراہم کرتا ہے۔"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"غلط صارف نام یا پاس ورڈ۔"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"‏اپنا صارف نام یا پاس ورڈ بھول گئے؟\n"<b>"google.com/accounts/recovery"</b>" ملاحظہ کریں۔"</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"اکاؤنٹ چیک کیا جا رہا ہے…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"‏آپ نے <xliff:g id="NUMBER_0">%d</xliff:g> بار اپنا PIN غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"آپ نے اپنا پاس ورڈ <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"آپ نے ٹیبلیٹ کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، ٹیبلیٹ فیکٹری ڈیفالٹ پر دوبارہ ترتیب دے دیا جائے گا اور صارف کا سبھی ڈیٹا ضائع ہو جائے گا۔"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"‏آپ نے TV کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، TV فیکٹری ڈیفالٹ پر ری سیٹ ہو جائے گا اور صارف کا سبھی ڈیٹا ضائع ہو جائے گا۔"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، فون فیکٹری ڈیفالٹ پر دوبارہ ترتیب دے دیا جائے گا اور صارف کا سبھی ڈیٹا ضائع ہو جائے گا۔"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"‏آپ نے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اپنا PIN غلط طریقے سے ٹائپ کیا ہے۔ \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_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">"‏آپ نے TV کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، TV فیکٹری ڈیفالٹ پر ری سیٹ ہو جائے گا اور صارف کا سبھی ڈیٹا ضائع ہو جائے گا۔"</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">"‏آپ نے TV کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوششیں کی ہیں۔ TV اب فیکٹری ڈیفالٹ پر ری سیٹ ہو جائے گا۔"</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">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا ٹیبلیٹ غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"‏آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا TV غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%d</xliff:g>‎ سیکنڈ میں دوبارہ کوشش کریں۔"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا فون غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%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> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کرکے اپنا TV غیر مقفل کرنے کو کہا جائے گا۔\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>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index c23476c..278ef6d 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -62,8 +62,8 @@
     <string name="needPuk2" msgid="4526033371987193070">"SIM kartani blokdan chiqarish uchun PUK2 raqamini kiriting."</string>
     <string name="enablePin" msgid="209412020907207950">"Ishlamadi, SIM/RUIM qulfni yoqish."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
-      <item quantity="other">Yana <xliff:g id="NUMBER_1">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM-karta qulflanadi.</item>
-      <item quantity="one">Yana <xliff:g id="NUMBER_0">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM-karta qulflanadi.</item>
+      <item quantity="other">Yana <xliff:g id="NUMBER_1">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM karta qulflanadi.</item>
+      <item quantity="one">Yana <xliff:g id="NUMBER_0">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM karta qulflanadi.</item>
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -344,7 +344,7 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ilovalarga tovush va ovoz chiqarish uchun foydalaniladigan karnay kabi global audio sozlamalarini o‘zgartirish uchun ruxsat beradi."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ovoz yozib olish"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Ilovaga mikrofon yordamida audio yozish uchun ruxsat beradi. Bu huquq ilovaga ruxsatingizsiz audio fayllarni yozib olishga ruxsat beradi."</string>
-    <string name="permlab_sim_communication" msgid="2935852302216852065">"SIM-kartaga buyruqlar yuborish"</string>
+    <string name="permlab_sim_communication" msgid="2935852302216852065">"SIM kartaga buyruqlar yuborish"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Dasturga SIM kartaga buyruqlar jo‘natishga ruxsat beradi. Bu juda ham xavfli."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"rasmga tushirish va videoga olish"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Ilovaga kameradan foydalanib rasm va videoga olishga ruxsat beradi. Bu ruxsat ilovaga sizdan tasdiqlashni so‘ramasdan kameradan foydalanishga imkon beradi."</string>
@@ -661,14 +661,14 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Qaytadan urining"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Qaytadan urining"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Yuzni tanitib qulfni ochishga urinish miqdoridan oshib ketdi"</string>
-    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM-karta yo‘q"</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Planshetingizga SIM-karta yo‘q."</string>
-    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Televizorda SIM-karta yo‘q."</string>
-    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefoningizga SIM-karta yo‘q."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM karta yo‘q"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Planshetingizga SIM karta yo‘q."</string>
+    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Televizorda SIM karta yo‘q."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefoningizga SIM karta yo‘q."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SIM kartani soling."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-karta solinmagan yoki uni o‘qib bo‘lmaydi. SIM-kartani soling."</string>
-    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Foydalanib bo‘lmaydigan SIM-karta."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kartangiz butunlay bloklab qo‘yilgan.\n Yangi SIM-karta olish uchun aloqa operatoringiz bilan bog‘laning."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM karta solinmagan yoki uni o‘qib bo‘lmaydi. SIM kartani soling."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Foydalanib bo‘lmaydigan SIM karta."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kartangiz butunlay bloklab qo‘yilgan.\n Yangi SIM karta olish uchun aloqa operatoringiz bilan bog‘laning."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Avvalgi musiqa"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Keyingi musiqa"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"To‘xtatib turish"</string>
@@ -678,19 +678,19 @@
     <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Oldinga o‘tkazish"</string>
     <string name="emergency_calls_only" msgid="6733978304386365407">"Faqat favqulodda qo‘ng‘iroqlar"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Tarmoq qulflangan"</string>
-    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-karta PUK kod bilan qulflangan."</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM karta PUK kod bilan qulflangan."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Foydalanuvchi qo‘llanmasiga qarang yoki Abonentlarni qo‘llab-quvvatlash markaziga murojaat qiling."</string>
-    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-karta qulflangan."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-karta qulfdan chiqarilmoqda…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Siz parolni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Siz PIN-kodni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Telefon qulfini ochish uchun yana <xliff:g id="NUMBER_1">%d</xliff:g> marta noto‘g‘ri urinish qilsangiz, sizdan Google hisobingizga kirish talab qilinadi. \n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizni qulfdan chiqarish uchun Google hisobingizga kirish talab qilinadi.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng qaytadan urining."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Telefon qulfini ochish uchun yana <xliff:g id="NUMBER_1">%d</xliff:g> marta noto‘g‘ri urinish qilsangiz, sizdan Google hisobingizga kirish talab qilinadi.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng qayta urining."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Planshet qulfini <xliff:g id="NUMBER_0">%d</xliff:g> marta ochishga urinib ko‘rdingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng, planshet ishlab chiqarilgan holatiga tiklanadi va barcha foydalanuvchi ma’lumotlari yo‘qoladi."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Siz televizorni qulfdan chiqarish parolini <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizda zavod sozlamalari qayta tiklanadi hamda undagi barcha ma’lumotlaringiz o‘chib ketadi."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon qulfini <xliff:g id="NUMBER_0">%d</xliff:g> marta ochishga urinib ko‘rdingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng, telefon ishlab chiqarilgan holatiga tiklanadi va barcha foydalanuvchi ma’lumotlari yo‘qoladi."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karta qulflangan."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM karta qulfdan chiqarilmoqda…"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan so‘ng qayta urining."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Siz parolni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan so‘ng qayta urining."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Siz PIN-kodni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan so‘ng qayta urining."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. Telefon qulfini ochish uchun yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta noto‘g‘ri urinish qilsangiz, sizdan Google hisobingizga kirish talab qilinadi. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng qayta urining."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizni qulfdan chiqarish uchun Google hisobingizga kirish talab qilinadi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng qaytadan urining."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. Telefon qulfini ochish uchun yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta noto‘g‘ri urinish qilsangiz, sizdan Google hisobingizga kirish talab qilinadi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng qayta urining."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Planshet qulfini <xliff:g id="NUMBER_0">%1$d</xliff:g> marta ochishga urinib ko‘rdingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng, planshet ishlab chiqarilgan holatiga tiklanadi va barcha foydalanuvchi ma’lumotlari yo‘qoladi."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Siz televizorni qulfdan chiqarish parolini <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizda zavod sozlamalari qayta tiklanadi hamda undagi barcha ma’lumotlaringiz o‘chib ketadi."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon qulfini <xliff:g id="NUMBER_0">%1$d</xliff:g> marta ochishga urinib ko‘rdingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng, telefon ishlab chiqarilgan holatiga tiklanadi va barcha foydalanuvchi ma’lumotlari yo‘qoladi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Planshet qulfini <xliff:g id="NUMBER">%d</xliff:g> marta ochishga urinib ko‘rdingiz. Planshet hozir ishlab chiqarilgan holatiga tiklanadi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Siz televizorni qulfdan chiqarish parolini <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Endi, televizoringizda zavod sozlamalari qayta tiklanadi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Telefon qulfini <xliff:g id="NUMBER">%d</xliff:g> marta ochishga urinib ko‘rdingiz. Telefon hozir ishlab chiqarilgan holatiga tiklanadi."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"so‘z"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"qator"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Ishlab chiqarish sinovi amalga oshmadi"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST amali faqatgina /system/app ichiga o‘rnatilgan paketlar bilan ishlay oladi."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST amalini bajarish uchun birorta ham paket topilmadi."</string>
@@ -1004,10 +1002,10 @@
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Siz buni keyinroq sozlamalar &gt; ilovalar menusidan o‘zgartirishingiz mumkin"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Doimo ruxsat berilsin"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Hech qachon ruxsat berilmasin"</string>
-    <string name="sim_removed_title" msgid="6227712319223226185">"SIM-karta olib tashlandi"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM karta olib tashlandi"</string>
     <string name="sim_removed_message" msgid="5450336489923274918">"Mobil tarmoqqa ulanish uchun faol SIM kartani joylang va qurilmani o‘chirib yoqing."</string>
     <string name="sim_done_button" msgid="827949989369963775">"Tayyor"</string>
-    <string name="sim_added_title" msgid="3719670512889674693">"SIM-karta qo‘shildi"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SIM karta qo‘shildi"</string>
     <string name="sim_added_message" msgid="7797975656153714319">"Mobil tarmoqqa ulanish uchun qurilmangizni o‘chirib yoqing."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"O‘chirib-yoqish"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Vaqtni o‘rnatish"</string>
@@ -1191,8 +1189,8 @@
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
     <string name="storage_internal" msgid="4891916833657929263">"Ichki xotira"</string>
-    <string name="storage_sd_card" msgid="3282948861378286745">"SD-karta"</string>
-    <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD-kartasi"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD karta"</string>
+    <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartasi"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB xotira"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB xotira qurilmasi"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB xotira"</string>
@@ -1268,10 +1266,10 @@
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM kartaning PIN kodini kiriting"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN kodni tering"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"Parol kiriting"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. To‘liqroq ma’lumot olish uchun tarmoq operatori bilan bog‘laning."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. To‘liqroq ma’lumot olish uchun tarmoq operatori bilan bog‘laning."</string>
     <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"So‘ralgan PIN kodni kiriting"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"So‘ralgan PIN kodni tasdiqlang"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-karta qulfi ochilmoqda…"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM karta qulfi ochilmoqda…"</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Xato PIN kodi."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 tadan 8 ta raqamgacha bo‘lgan PIN kodni kiriting."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kod 8 ta raqam bo‘lishi shart."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Foydalanuvchi nomi yoki parol xato."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Foydalanuvchi nomingiz yoki parolingizni unutdingizmi?\n "<b>"google.com/accounts/recovery"</b>"ga tashrif buyuring."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Hisob tekshirilmoqda…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Siz PIN-kodni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Siz parolni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planshet qulfini ochish uchun <xliff:g id="NUMBER_0">%d</xliff:g> marta muvaffaqiyatsiz urindingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng planshetning zavod sozlamalari tiklanadi va barcha foydalanuvchi ma’lumotlari o‘chiriladi."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Siz televizorni qulfdan chiqarish parolini <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizda zavod sozlamalari qayta tiklanadi hamda undagi barcha ma’lumotlaringiz o‘chib ketadi."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon qulfini ochish uchun <xliff:g id="NUMBER_0">%d</xliff:g> marta muvaffaqiyatsiz urindingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng telefonning zavod sozlamalari tiklanadi va barcha foydalanuvchi ma’lumotlari o‘chiriladi."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Siz PIN-kodni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Siz parolni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planshet qulfini ochish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta muvaffaqiyatsiz urindingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng planshetning zavod sozlamalari tiklanadi va barcha foydalanuvchi ma’lumotlari o‘chiriladi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Siz televizorni qulfdan chiqarish parolini <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizda zavod sozlamalari qayta tiklanadi hamda undagi barcha ma’lumotlaringiz o‘chib ketadi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon qulfini ochish uchun <xliff:g id="NUMBER_0">%1$d</xliff:g> marta muvaffaqiyatsiz urindingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishlardan so‘ng telefonning zavod sozlamalari tiklanadi va barcha foydalanuvchi ma’lumotlari o‘chiriladi."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Planshet qulfini ochish uchun <xliff:g id="NUMBER">%d</xliff:g> marta muvaffaqiyatsiz urinib ko‘rdingiz. Planshetning hozir zavod sozlamari tiklanadi."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Siz televizorni qulfdan chiqarish parolini <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Endi, televizoringizda zavod sozlamalari qayta tiklanadi."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon qulfini ochish uchun <xliff:g id="NUMBER">%d</xliff:g> marta muvaffaqiyatsiz urinib ko‘rdingiz. Telefonning hozir zavod sozlamari tiklanadi."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz chizmali kalitni  <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, planshet qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizni qulfdan chiqarish uchun sizda e-pochta hisobingizga kirish talab qilinadi.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng qaytadan urining."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri chizdingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, telefon qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz chizmali kalitni  <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, planshet qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri kiritdingiz. Agar uni yana <xliff:g id="NUMBER_1">%2$d</xliff:g> marta noto‘g‘ri kiritsangiz, televizoringizni qulfdan chiqarish uchun sizda e-pochta hisobingizga kirish talab qilinadi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng qaytadan urining."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri chizdingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, telefon qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"O‘chirish"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ovoz balandligi tavsiya etilgan darajadan ham yuqori ko‘tarilsinmi?\n\nUzoq vaqt davomida baland ovozda tinglash eshitish qobiliyatingizga salbiy ta’sir ko‘rsatishi mumkin."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index c7dbc5c..439fe25 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Vui lòng xem Hướng dẫn người dùng hoặc liên hệ với Bộ phận chăm sóc khách hàng."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Thẻ SIM đã bị khóa."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Đang mở khóa thẻ SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa. \n\nVui lòng thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Bạn đã nhập sai mã PIN <xliff:g id="NUMBER_0">%d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng thông tin đăng nhập Google của mình.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Bạn đã vẽ sai hình mở khóa <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, bạn sẽ được yêu cầu mở khóa TV bằng cách đăng nhập vào Google.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng thông tin đăng nhập Google của bạn.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Bạn đã mở khóa máy tính bảng không đúng cách <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Bạn đã mở khóa TV sai <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, TV sẽ được đặt lại về cài đặt mặc định ban đầu và toàn bộ dữ liệu người dùng sẽ bị mất."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Bạn đã mở khóa điện thoại không đúng cách <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần vẽ không chính xác hình mở khóa. \n\nVui lòng thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần nhập sai mật khẩu. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Bạn đã nhập sai mã PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng thông tin đăng nhập Google của mình.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Bạn đã vẽ sai hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, bạn sẽ được yêu cầu mở khóa TV bằng cách đăng nhập vào Google.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần vẽ không chính xác hình mở khóa. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng thông tin đăng nhập Google của bạn.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Bạn đã mở khóa máy tính bảng không đúng cách <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Bạn đã mở khóa TV sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, TV sẽ được đặt lại về cài đặt mặc định ban đầu và toàn bộ dữ liệu người dùng sẽ bị mất."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Bạn đã mở khóa điện thoại không đúng cách <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Bạn đã mở khóa máy tính bảng không đúng cách <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, máy tính bảng sẽ được đặt lại về mặc định ban đầu."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Bạn đã mở khóa TV sai <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, TV sẽ được đặt lại về cài đặt mặc định ban đầu."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Bạn đã mở khóa điện thoại không đúng cách <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"từ"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"liên kết"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"dòng"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Thử nghiệm ban đầu không thành công"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Tác vụ FACTORY_TEST chỉ được hỗ trợ cho các gói được cài đặt trong /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Không tìm thấy gói cung cấp tác vụ FACTORY_TEST."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bạn quên tên người dùng hoặc mật khẩu?\nHãy truy cập "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Đang kiểm tra tài khoản…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mã PIN. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Bạn đã mở khóa TV sai <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, TV sẽ được đặt lại về cài đặt mặc định ban đầu và toàn bộ dữ liệu người dùng sẽ bị mất."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần nhập sai mã PIN. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần nhập sai mật khẩu. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần vẽ không chính xác hình mở khóa. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Bạn đã mở khóa TV sai <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, TV sẽ được đặt lại về cài đặt mặc định ban đầu và toàn bộ dữ liệu người dùng sẽ bị mất."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần mở khóa điện thoại không đúng cách. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Bây giờ, máy tính bảng sẽ được đặt lại về mặc định ban đầu."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Bạn đã mở khóa TV sai <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, TV sẽ được đặt lại về cài đặt mặc định ban đầu."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Bạn đã vẽ sai hình mở khóa <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, bạn sẽ được yêu cầu mở khóa TV bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Bạn đã vẽ sai hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần mở khóa không thành công nữa, bạn sẽ được yêu cầu mở khóa TV bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%1$d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Xóa"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Bạn tăng âm lượng lên quá mức khuyên dùng?\n\nViệc nghe ở mức âm lượng cao trong thời gian dài có thể gây tổn thương thính giác của bạn."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 3a75610..b3c70a5 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -376,10 +376,10 @@
     <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"允许应用更改平板电脑的时区。"</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"允许应用更改电视的时区。"</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"允许应用更改手机的时区。"</string>
-    <string name="permlab_getAccounts" msgid="1086795467760122114">"查找设备上的帐户"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"允许该应用获取平板电脑已知的帐户列表,其中可能包括由已安装的应用创建的所有帐户。"</string>
-    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"允许应用获取电视已知的帐户列表,其中可能包括由已安装的应用创建的所有帐户。"</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"允许该应用获取手机已知的帐户列表,其中可能包括由已安装的应用创建的所有帐户。"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"查找设备上的帐号"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"允许该应用获取平板电脑已知的帐号列表,其中可能包括由已安装的应用创建的所有帐号。"</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"允许应用获取电视已知的帐号列表,其中可能包括由已安装的应用创建的所有帐号。"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"允许该应用获取手机已知的帐号列表,其中可能包括由已安装的应用创建的所有帐号。"</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"查看网络连接"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"允许该应用查看网络连接的相关信息,例如存在和连接的网络。"</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"拥有完全的网络访问权限"</string>
@@ -436,11 +436,11 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指纹图标"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"读取同步设置"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允许该应用读取某个帐户的同步设置。例如,此权限可确定“联系人”应用是否与某个帐户同步。"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允许该应用读取某个帐号的同步设置。例如,此权限可确定“联系人”应用是否与某个帐号同步。"</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"启用和停用同步"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允许该应用修改某个帐户的同步设置。例如,此权限可用于在“联系人”应用与某个帐户之间启用同步。"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允许该应用修改某个帐号的同步设置。例如,此权限可用于在“联系人”应用与某个帐号之间启用同步。"</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"读取同步统计信息"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"允许该应用读取某个帐户的同步统计信息,包括同步活动历史记录和同步数据量。"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"允许该应用读取某个帐号的同步统计信息,包括同步活动历史记录和同步数据量。"</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"读取您的USB存储设备中的内容"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"读取您的SD卡中的内容"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"允许应用读取您USB存储设备中的内容。"</string>
@@ -682,23 +682,23 @@
     <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">%d</xliff:g> 次画错解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次输错密码。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次输错了PIN码。\n\n请在<xliff:g id="NUMBER_1">%d</xliff:g>秒后重试。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的 Google 登录信息解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的 Google 登录信息解锁电视。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的 Google 登录信息解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁平板电脑。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,平板电脑将恢复为出厂默认设置,所有用户数据都会丢失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁电视。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,电视将恢复为出厂默认设置,所有用户数据都会丢失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%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">"您已经<xliff:g id="NUMBER_0">%1$d</xliff:g>次输错了PIN码。\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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁平板电脑。平板电脑现在将恢复为出厂默认设置。"</string>
     <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_glogin_forgot_pattern" msgid="2588521501166032747">"帐户解锁"</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>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"要解除锁定,请使用您的Google帐号登录。"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"用户名(电子邮件)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"密码"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"登录"</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"字"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"链接"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"行"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="AMPM">%P</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="AMPM">%p</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出厂测试失败"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"只有安装在/system/app中的软件包支持FACTORY_TEST操作。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"找不到提供FACTORY_TEST操作的软件包。"</string>
@@ -1090,13 +1088,13 @@
     <string name="ime_action_default" msgid="2840921885558045721">"执行"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"拨打电话\n<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"创建电话号码为\n<xliff:g id="NUMBER">%s</xliff:g> 的联系人"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"以下一个或多个应用请求获得相应权限,以便在当前和以后访问您的帐户。"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"以下一个或多个应用请求获得相应权限,以便在当前和以后访问您的帐号。"</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"您是否同意此请求?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"访问权限请求"</string>
     <string name="allow" msgid="7225948811296386551">"允许"</string>
     <string name="deny" msgid="2081879885755434506">"拒绝"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"权限请求"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐户 <xliff:g id="ACCOUNT">%s</xliff:g>\n 提出权限请求。"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐号 <xliff:g id="ACCOUNT">%s</xliff:g>\n 提出权限请求。"</string>
     <string name="forward_intent_to_owner" msgid="1207197447013960896">"您目前是在工作资料之外使用此应用"</string>
     <string name="forward_intent_to_work" msgid="621480743856004612">"您目前是在工作资料内使用此应用"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string>
@@ -1145,13 +1143,13 @@
     <string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"超出删除限制"</string>
-    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"帐户 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 在进行“<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>”同步时删除了 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 项内容。您要如何处理这些删除的内容?"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"帐号 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 在进行“<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>”同步时删除了 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 项内容。您要如何处理这些删除的内容?"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"删除这些内容"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"撤消删除"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"目前不进行任何操作"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"选择帐户"</string>
-    <string name="add_account_label" msgid="2935267344849993553">"添加帐户"</string>
-    <string name="add_account_button_label" msgid="3611982894853435874">"添加帐户"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"选择帐号"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"添加帐号"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"添加帐号"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"增大"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"减小"</string>
     <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"触摸 <xliff:g id="VALUE">%s</xliff:g> 次并按住。"</string>
@@ -1278,25 +1276,25 @@
     <string name="kg_invalid_puk" msgid="3638289409676051243">"请重新输入正确的PUK码。如果尝试错误次数过多,SIM卡将永久停用。"</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN码不匹配"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"图案尝试次数过多"</string>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的Google帐户。"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的Google帐号。"</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"用户名(电子邮件地址)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"密码"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"登录"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"用户名或密码无效。"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘记了用户名或密码?\n请访问 "<b>"google.com/accounts/recovery"</b>"。"</string>
-    <string name="kg_login_checking_password" msgid="1052685197710252395">"正在检查帐户…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次输错了PIN码。\n\n请在<xliff:g id="NUMBER_1">%d</xliff:g>秒后重试。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次输错密码。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁平板电脑。如果再尝试  <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,平板电脑将恢复为出厂默认设置,所有用户数据都会丢失。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁电视。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,电视将恢复为出厂默认设置,所有用户数据都会丢失。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,手机将恢复为出厂默认设置,所有用户数据都会丢失。"</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"正在检查帐号…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经<xliff:g id="NUMBER_0">%1$d</xliff:g>次输错了PIN码。\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_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">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用电子邮件帐户解锁电视。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 0bc4982..ddafe6d 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤繪製解鎖圖案。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,您將需要使用 Google 登入帳戶解鎖電視。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,平板電腦將恢復原廠設定,所有使用者資料均會遺失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖電視。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,電視將重設至原廠設定,所有使用者資料亦會遺失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。平板電腦現在會重設為原廠預設值。"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"字詞"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"連結"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"行"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"原廠測試失敗"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"只有安裝在 /system/app 裡的程式套件才能支援 FACTORY_TEST 操作。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"沒有可提供 FACTORY_TEST 操作的套件。"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"無效的使用者名稱或密碼。"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘記使用者名稱或密碼?\n請瀏覽 "<b>"google.com/accounts/recovery"</b>"。"</string>
     <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">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有使用者資料均會失去。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤解鎖電視。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,電視將重設至原廠設定,所有使用者資料亦會遺失。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,手機將回復原廠設定,所有使用者資料均會失去。"</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_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">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已 <xliff:g id="NUMBER_0">%d</xliff:g> 次錯誤繪製解鎖圖案。如再解鎖失敗 <xliff:g id="NUMBER_1">%d</xliff:g> 次,您將需要使用電郵帳戶解鎖電視。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 7bab301..1163137 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -682,15 +682,15 @@
     <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">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次嘗試機會。如果失敗次數超過限制,您就必須登入 Google 帳戶才能解鎖電視。\n\n請過 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"您嘗試解鎖電視已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,電視將恢復原廠設定,所有使用者資料都會遺失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%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_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>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,平板電腦現在將恢復原廠設定。"</string>
     <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>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"字詞"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"連結"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"行"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出廠測試失敗"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"只有安裝在 /system/app 裡的程式才能支援 FACTORY_TEST 操作。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"找不到提供 FACTORY_TEST 的程式。"</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"使用者名稱或密碼無效。"</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘了使用者名稱或密碼?\n請前往 "<b>"google.com/accounts/recovery"</b>"。"</string>
     <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">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"您嘗試解鎖電視已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,電視將恢復原廠設定,所有使用者資料都會遺失。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,手機將恢復原廠設定,所有使用者資料都會遺失。"</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_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">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次嘗試機會。如果失敗次數超過限制,您就必須使用電子郵件帳戶才能解鎖電視。\n\n請過 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%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>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 8b53f9b..9557f58 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -682,15 +682,15 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Sicela ubone Isiqondisi Somsebenzisi noma xhumana Nokunakekela Ikhasimende"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Ikhadi le-SIM livaliwe."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ivula ikhadi le-SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Udwebe iphathini yakho yokuvula ngendlela engafanele izinkathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Zama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. \n\nZama futhi <xliff:g id="NUMBER_1">%d</xliff:g> imizuzwna."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ubhale i-PIN ykho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. \n\nZama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google.\n\n Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Udwebele ngokungalungile iphethini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kwemizamo engaphumelelanga engu-<xliff:g id="NUMBER_1">%d</xliff:g> ngaphezulu, uzocelwa ukuthi uvule i-TV yakho usebenzisa ukungena kwakho ngemvume kwe-Google.\n\n Zama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g> Emumva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emuva kwamasekhondi angu- <xliff:g id="NUMBER_2">%d</xliff:g>"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Uzame ngokusebenzisa indlela engafanele ukuvula izikhathi <xliff:g id="NUMBER_0">%d</xliff:g> ze-tablet. Ngemuva <xliff:g id="NUMBER_1">%d</xliff:g> kokuzama kaningana okuyimpumelelo i-tablet izobuyela kwizimo zasembonini futhi yonke imininingo yomsebenzisi izolahleka."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Uzame ukuvula ngokungalungile i-TV ngezikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kwemizamo engaphumelelanga engu-<xliff:g id="NUMBER_1">%d</xliff:g> ngaphezulu, i-TV izosethelwa kabusha kokuzenzakalelayo kwasekuqaleni futhi yonke idatha yomsebenzisi izolahleka."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Uzame ngokusebenzisa indlela engafanele ukuvula izikhathi <xliff:g id="NUMBER_0">%d</xliff:g> zocingo. Ngemuva <xliff:g id="NUMBER_1">%d</xliff:g> kokuzama kaningana ngaphandle kwempumelelo, ucingo luzobiyiselwa kwizimiso zasembonini futhi yonke imininingo yomsebenzisi izolahleka."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Udwebe iphathini yakho yokuvula ngendlela engafanele izinkathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Zama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%1$d</xliff:g> izikhathi. \n\nZama futhi <xliff:g id="NUMBER_1">%2$d</xliff:g> imizuzwna."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ubhale i-PIN ykho ngendlela engafanele <xliff:g id="NUMBER_0">%1$d</xliff:g> izikhathi. \n\nZama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Emva <xliff:g id="NUMBER_1">%2$d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google.\n\n Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Udwebele ngokungalungile iphethini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphumelelanga engu-<xliff:g id="NUMBER_1">%2$d</xliff:g> ngaphezulu, uzocelwa ukuthi uvule i-TV yakho usebenzisa ukungena kwakho ngemvume kwe-Google.\n\n Zama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g> Emumva kweminye imizamo engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emuva kwamasekhondi angu- <xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Uzame ngokusebenzisa indlela engafanele ukuvula izikhathi <xliff:g id="NUMBER_0">%1$d</xliff:g> ze-tablet. Ngemuva <xliff:g id="NUMBER_1">%2$d</xliff:g> kokuzama kaningana okuyimpumelelo i-tablet izobuyela kwizimo zasembonini futhi yonke imininingo yomsebenzisi izolahleka."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Uzame ukuvula ngokungalungile i-TV ngezikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphumelelanga engu-<xliff:g id="NUMBER_1">%2$d</xliff:g> ngaphezulu, i-TV izosethelwa kabusha kokuzenzakalelayo kwasekuqaleni futhi yonke idatha yomsebenzisi izolahleka."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Uzame ngokusebenzisa indlela engafanele ukuvula izikhathi <xliff:g id="NUMBER_0">%1$d</xliff:g> zocingo. Ngemuva <xliff:g id="NUMBER_1">%2$d</xliff:g> kokuzama kaningana ngaphandle kwempumelelo, ucingo luzobiyiselwa kwizimiso zasembonini futhi yonke imininingo yomsebenzisi izolahleka."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Uzame ukuvula ngendlela engafanele izikhathi <xliff:g id="NUMBER">%d</xliff:g> ze-tablet. I-tablet manje seyizosethwa kabusha ibe yizimiso zasembonini."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Uzame ngokungalungile ukuvula i-TV izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. I-TV manje izosethelwa kabusha kokuzenzakalelayo kwasekuqaleni."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Uzame ukuvula ngendlela engafanele izikhathi <xliff:g id="NUMBER">%d</xliff:g> zocingo. Ucingo manje seyizosethwa kabusha ibe yizimiso zasembonini."</string>
@@ -742,8 +742,6 @@
     <string name="granularity_label_word" msgid="7075570328374918660">"igama"</string>
     <string name="granularity_label_link" msgid="5815508880782488267">"isixhumanisi"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"ulayini"</string>
-    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
-    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Ukuhlola kwemboni kwehlulekile"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Isenzo SOKUHLOLA_KWASEMBONINI sisekelwa kuphela amaphakheji afakwe kwisistimu/uhlelokusebenza."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Ayikho iphakheji etholakele enikeze isenzo SOKUHLOLA KWASEMBONINI."</string>
@@ -1285,18 +1283,18 @@
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Igama lomsebezisi elingalungile noma iphasiwedi."</string>
     <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?\nVakashela"<b>"google.com/accounts/recovery"</b></string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Ukuhlola i-akhawunti…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Ubhale iphinikhodi ykho ngendlela engafanele izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Uzame ngokusebenzisa indlela engafanele ukuvula ithebhulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ithebhulethi izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Uzame ukuvula ngokungalungile i-TV ngezikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kwemizamo engaphumelelanga engu-<xliff:g id="NUMBER_1">%d</xliff:g> ngaphezulu, i-TV izosethelwa kabusha kokuzenzakalelayo kwasekuqaleni futhi yonke idatha yomsebenzisi izolahleka."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Uzame ngokusebenzisa indlela engafanele ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ifoni izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Ubhale iphinikhodi ykho ngendlela engafanele izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%1$d</xliff:g> izikhathi. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Uzame ngokusebenzisa indlela engafanele ukuvula ithebhulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, ithebhulethi izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Uzame ukuvula ngokungalungile i-TV ngezikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphumelelanga engu-<xliff:g id="NUMBER_1">%2$d</xliff:g> ngaphezulu, i-TV izosethelwa kabusha kokuzenzakalelayo kwasekuqaleni futhi yonke idatha yomsebenzisi izolahleka."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Uzame ngokusebenzisa indlela engafanele ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, ifoni izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ithebhulethi manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Uzame ngokungalungile ukuvula i-TV izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. I-TV manje izosethelwa kabusha kokuzenzakalelayo kwasekuqaleni."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ifoni manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google.\n\n Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Udwebele ngokungalungile iphethini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%d</xliff:g> engaphumelelanga, uzocelwa ukuthi uvule i-TV yakho usebenzisa i-akhawunti ye-imeyili.\n\n Zama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> amasekhondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Emva <xliff:g id="NUMBER_1">%2$d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google.\n\n Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Udwebele ngokungalungile iphethini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphezulu kwengu-<xliff:g id="NUMBER_1">%2$d</xliff:g> engaphumelelanga, uzocelwa ukuthi uvule i-TV yakho usebenzisa i-akhawunti ye-imeyili.\n\n Zama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%1$d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%3$d</xliff:g> amasekhondi."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Susa"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Khuphukisa ivolumu ngaphezu kweleveli enconyiwe?\n\nUkulalela ngevolumu ephezulu izikhathi ezide kungahle kulimaze ukuzwa kwakho."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d7dd3ec..50cf302 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7714,6 +7714,7 @@
     <declare-styleable name="PreferenceFragment">
         <!-- The layout for the PreferenceFragment. This should rarely need to be changed. -->
         <attr name="layout" />
+        <attr name="divider" />
     </declare-styleable>
 
     <!-- Base attributes available to PreferenceActivity. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 07ac471..e376903 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -571,6 +571,11 @@
          single integer, with higher numbers considered to be better. -->
     <attr name="priority" format="integer" />
 
+    <!-- Indicate if this component is aware of encryption lifecycle, and can be
+         safely run before the user has entered their credentials (such as a lock
+         pattern or PIN). -->
+    <attr name="encryptionAware" format="boolean" />
+
     <!-- Specify how an activity should be launched.  See the
          <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
          Stack</a> document for important information on how these options impact
@@ -1277,6 +1282,8 @@
         <attr name="usesCleartextTraffic" />
         <attr name="multiArch" />
         <attr name="extractNativeLibs" />
+        <attr name="forceDeviceEncrypted" format="boolean" />
+        <attr name="encryptionAware" />
     </declare-styleable>
     <!-- The <code>permission</code> tag declares a security permission that can be
          used to control access from other packages to specific components or
@@ -1652,6 +1659,7 @@
         <attr name="enabled" />
         <attr name="exported" />
         <attr name="singleUser" />
+        <attr name="encryptionAware" />
     </declare-styleable>
 
     <!-- Attributes that can be supplied in an AndroidManifest.xml
@@ -1735,6 +1743,7 @@
              with it is through the Service API (binding and starting). -->
         <attr name="isolatedProcess" format="boolean" />
         <attr name="singleUser" />
+        <attr name="encryptionAware" />
     </declare-styleable>
 
     <!-- The <code>receiver</code> tag declares an
@@ -1770,6 +1779,7 @@
         <attr name="enabled" />
         <attr name="exported" />
         <attr name="singleUser" />
+        <attr name="encryptionAware" />
     </declare-styleable>
 
     <!-- The <code>activity</code> tag declares an
@@ -1842,6 +1852,7 @@
         <attr name="supportsPictureInPicture" />
         <attr name="lockTaskMode" />
         <attr name="showForAllUsers" />
+        <attr name="encryptionAware" />
     </declare-styleable>
 
     <!-- The <code>activity-alias</code> tag declares a new
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 76f7062..b87d9e2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -411,7 +411,7 @@
     <bool translatable="false" name="config_wifi_revert_country_code_on_cellular_loss">false</bool>
 
     <!-- Boolean indicating whether or not wifi firmware debugging is enabled -->
-    <bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">false</bool>
+    <bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">true</bool>
 
     <!-- Integer specifying the basic autojoin parameters -->
     <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_threshold">-65</integer>
@@ -1530,8 +1530,8 @@
     <!-- If the time difference is greater than this threshold in milliseconds,
          then update the time. -->
     <integer name="config_ntpThreshold">5000</integer>
-    <!-- Timeout to wait for NTP server response. -->
-    <integer name="config_ntpTimeout">20000</integer>
+    <!-- Timeout to wait for NTP server response in milliseconds. -->
+    <integer name="config_ntpTimeout">5000</integer>
 
     <!-- Default network policy warning threshold, in megabytes. -->
     <integer name="config_networkPolicyDefaultWarning">2048</integer>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index bfb0d10..28756f5 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -45,8 +45,12 @@
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <dimen name="status_bar_edge_ignore">5dp</dimen>
 
-    <!-- Width of a divider bar used to resize docked stacks. -->
-    <dimen name="docked_stack_divider_thickness">24dp</dimen>
+    <!-- Width of the window of the divider bar used to resize docked stacks. -->
+    <dimen name="docked_stack_divider_thickness">48dp</dimen>
+
+    <!-- How much the content in the divider is inset from the window bounds when resting. Used to
+         calculate the bounds of the stacks-->
+    <dimen name="docked_stack_divider_insets">18dp</dimen>
 
     <!-- Min width for a tablet device -->
     <dimen name="min_xlarge_screen_width">800dp</dimen>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 695dafa..9d5e5ac 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -23,12 +23,14 @@
   <item type="id" name="empty" />
   <item type="id" name="hint" />
   <item type="id" name="icon" />
+  <item type="id" name="icon_frame" />
   <item type="id" name="icon_badge" />
   <item type="id" name="icon1" />
   <item type="id" name="icon2" />
   <item type="id" name="input" />
   <item type="id" name="left_icon" />
   <item type="id" name="list" />
+  <item type="id" name="list_container" />
   <item type="id" name="menu" />
   <item type="id" name="message" />
   <item type="id" name="primary" />
@@ -48,6 +50,7 @@
   <item type="id" name="lock_screen" />
   <item type="id" name="edit" />
   <item type="id" name="widget_frame" />
+  <item type="id" name="switch_widget" />
   <item type="id" name="button1" />
   <item type="id" name="button2" />
   <item type="id" name="button3" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 037f1c4..54e43c8 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2679,6 +2679,9 @@
     <public type="attr" name="contextPopupMenuStyle" />
     <public type="attr" name="textAppearancePopupMenuHeader" />
     <public type="attr" name="windowBackgroundFallback" />
+    <public type="attr" name="forceDeviceEncrypted" />
+    <public type="attr" name="encryptionAware" />
+    <public type="attr" name="preferenceFragmentStyle" />
 
     <public type="style" name="Theme.Material.DayNight" />
     <public type="style" name="Theme.Material.DayNight.DarkActionBar" />
@@ -2699,5 +2702,8 @@
     <public type="style" name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" />
 
     <public type="id" name="accessibilityActionSetProgress" />
+    <public type="id" name="icon_frame" />
+    <public type="id" name="list_container" />
+    <public type="id" name="switch_widget" />
 
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7584d4d..faa76f2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1781,72 +1781,72 @@
     <!-- For the unlock screen, Information message shown in dialog when user has too many failed attempts at
          drawing the unlock pattern -->
     <string name="lockscreen_too_many_failed_attempts_dialog_message">
-        You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+        You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%2$d</xliff:g> seconds.
     </string>
 
     <!-- For the unlock screen, Information message shown in dialog when user has too many failed attempts at
          entering the password -->
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message">
-        You have incorrectly typed your password <xliff:g id="number">%d</xliff:g> times.
-        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+        You have incorrectly typed your password <xliff:g id="number">%1$d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%2$d</xliff:g> seconds.
     </string>
 
     <!-- For the unlock screen, Information message shown in dialog when user has too many failed attempts at
          entering the PIN -->
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message">
-        You have incorrectly typed your PIN <xliff:g id="number">%d</xliff:g> times.
-        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+        You have incorrectly typed your PIN <xliff:g id="number">%1$d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%2$d</xliff:g> seconds.
     </string>
 
     <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
          where they will be locked out and may have to enter an alternate username/password to unlock the phone -->
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet">
-        You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+        You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        you will be asked to unlock your tablet using your Google signin.\n\n
-       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+       Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
     </string>
 
     <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
          where they will be locked out and may have to enter an alternate username/password to unlock the phone -->
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv">
-        You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+        You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        you will be asked to unlock your TV using your Google signin.\n\n
-       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+       Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
     </string>
 
     <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
          where they will be locked out and may have to enter an alternate username/password to unlock the phone -->
     <string name="lockscreen_failed_attempts_almost_glogin" product="default">
-        You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+        You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        you will be asked to unlock your phone using your Google signin.\n\n
-       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+       Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
     </string>
 
     <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
          where the device will be wiped. -->
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet">
-       You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        the tablet will be reset to factory default and all user data will be lost.
     </string>
 
     <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
          where the device will be wiped. -->
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv">
-       You have incorrectly attempted to unlock the TV <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly attempted to unlock the TV <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        the TV will be reset to factory default and all user data will be lost.
     </string>
 
     <!-- For the unlock screen, informational message shown in dialog when user is almost at the limit
          where the device will be wiped. -->
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default">
-       You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        the phone will be reset to factory default and all user data will be lost.
     </string>
 
@@ -1982,12 +1982,6 @@
     <!-- Label for granularity to traverse the content on an AccessibilityNodeInfo by line. Only spoken to the user. [CHAR LIMIT=NONE] -->
     <string name="granularity_label_line">line</string>
 
-    <!-- A format string for 12-hour time of day, just the hour, not the minute, with lower-case "am" or "pm" (example: "3pm"). -->
-    <string name="hour_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="pm">%P</xliff:g>"</string>
-
-    <!-- A format string for 12-hour time of day, just the hour, not the minute, with capital "AM" or "PM" (example: "3PM"). -->
-    <string name="hour_cap_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="PM">%p</xliff:g>"</string>
-
     <!-- Title of the alert when something went wrong in the factory test. -->
     <string name="factorytest_failed">Factory test failed</string>
     <!-- Error message displayed when a non-system application tries to start a factory test. -->
@@ -3532,34 +3526,34 @@
     <string name="kg_login_checking_password">Checking account\u2026</string>
     <!-- Message shown in dialog when max number of attempts are reached for PIN screen of keyguard -->
     <string name="kg_too_many_failed_pin_attempts_dialog_message">
-        You have incorrectly typed your PIN <xliff:g id="number">%d</xliff:g> times.
-        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+        You have incorrectly typed your PIN <xliff:g id="number">%1$d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%2$d</xliff:g> seconds.
     </string>
     <!-- Message shown in dialog when max number of attempts are reached for password screen of keyguard -->
     <string name="kg_too_many_failed_password_attempts_dialog_message">
-        You have incorrectly typed your password <xliff:g id="number">%d</xliff:g> times.
-        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+        You have incorrectly typed your password <xliff:g id="number">%1$d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%2$d</xliff:g> seconds.
     </string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message">
-        You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+        You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%2$d</xliff:g> seconds.
     </string>
     <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet">
-       You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly attempted to unlock the tablet <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        the tablet will be reset to factory default and all user data will be lost.
     </string>
     <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
     <string name="kg_failed_attempts_almost_at_wipe" product="tv">
-       You have incorrectly attempted to unlock the TV <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly attempted to unlock the TV <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        the TV will be reset to factory default and all user data will be lost.
     </string>
     <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
     <string name="kg_failed_attempts_almost_at_wipe" product="default">
-       You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly attempted to unlock the phone <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        the phone will be reset to factory default and all user data will be lost.
     </string>
     <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
@@ -3580,26 +3574,26 @@
     <!-- Message shown in dialog when user is almost at the limit where they will be
     locked out and may have to enter an alternate username/password to unlock the phone -->
     <string name="kg_failed_attempts_almost_at_login" product="tablet">
-       You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        you will be asked to unlock your tablet using an email account.\n\n
-       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+       Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
     </string>
     <!-- Message shown in dialog when user is almost at the limit where they will be
     locked out and may have to enter an alternate username/password to unlock the phone -->
     <string name="kg_failed_attempts_almost_at_login" product="tv">
-       You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        you will be asked to unlock your TV using an email account.\n\n
-       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+       Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
     </string>
     <!-- Message shown in dialog when user is almost at the limit where they will be
     locked out and may have to enter an alternate username/password to unlock the phone -->
     <string name="kg_failed_attempts_almost_at_login" product="default">
-       You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
-       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       You have incorrectly drawn your unlock pattern <xliff:g id="number">%1$d</xliff:g> times.
+       After <xliff:g id="number">%2$d</xliff:g> more unsuccessful attempts,
        you will be asked to unlock your phone using an email account.\n\n
-       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+       Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
     </string>
     <!-- Sequence of characters used to separate message strings in keyguard. Typically just em-dash
          with spaces on either side. [CHAR LIMIT=3] -->
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 58640eb..4b2a451 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -40,6 +40,7 @@
         <item name="layout">@layout/preference_list_fragment_material</item>
         <item name="paddingStart">@dimen/preference_fragment_padding_side_material</item>
         <item name="paddingEnd">@dimen/preference_fragment_padding_side_material</item>
+        <item name="divider">?attr/listDivider</item>
     </style>
 
     <style name="PreferenceActivity.Material">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ba28e81..6820c25 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -162,7 +162,7 @@
   <java-symbol type="id" name="submit_area" />
   <java-symbol type="id" name="switch_new" />
   <java-symbol type="id" name="switch_old" />
-  <java-symbol type="id" name="switchWidget" />
+  <java-symbol type="id" name="switch_widget" />
   <java-symbol type="id" name="text" />
   <java-symbol type="id" name="time" />
   <java-symbol type="id" name="time_current" />
@@ -642,8 +642,6 @@
   <java-symbol type="string" name="gpsVerifNo" />
   <java-symbol type="string" name="gpsVerifYes" />
   <java-symbol type="string" name="gsm_alphabet_default_charset" />
-  <java-symbol type="string" name="hour_ampm" />
-  <java-symbol type="string" name="hour_cap_ampm" />
   <java-symbol type="string" name="httpError" />
   <java-symbol type="string" name="httpErrorAuth" />
   <java-symbol type="string" name="httpErrorConnect" />
@@ -1450,6 +1448,8 @@
   <java-symbol type="anim" name="dock_left_exit" />
   <java-symbol type="anim" name="dock_right_enter" />
   <java-symbol type="anim" name="dock_right_exit" />
+  <java-symbol type="anim" name="fade_in" />
+  <java-symbol type="anim" name="fade_out" />
   <java-symbol type="anim" name="voice_activity_close_exit" />
   <java-symbol type="anim" name="voice_activity_close_enter" />
   <java-symbol type="anim" name="voice_activity_open_exit" />
@@ -1481,6 +1481,7 @@
   <java-symbol type="bool" name="config_supportAutoRotation" />
   <java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
   <java-symbol type="dimen" name="docked_stack_divider_thickness" />
+  <java-symbol type="dimen" name="docked_stack_divider_insets" />
   <java-symbol type="dimen" name="navigation_bar_height" />
   <java-symbol type="dimen" name="navigation_bar_height_landscape" />
   <java-symbol type="dimen" name="navigation_bar_width" />
@@ -1724,7 +1725,6 @@
   <java-symbol type="integer" name="config_undockedHdmiRotation" />
   <java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" />
   <java-symbol type="layout" name="am_compat_mode_dialog" />
-  <java-symbol type="layout" name="docked_stack_divider" />
   <java-symbol type="layout" name="launch_warning" />
   <java-symbol type="layout" name="safe_mode" />
   <java-symbol type="layout" name="simple_list_item_2_single_choice" />
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
index 7164747..998c72a 100644
--- a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
@@ -811,6 +811,65 @@
     }
 
     @SmallTest
+    public void testEndBeforeStart() throws Throwable {
+        // This test calls two animators that are not yet started. One animator has completed a
+        // previous run but hasn't started since then, the other one has never run. When end() is
+        // called on these two animators, we expected their animation listeners to receive both
+        // onAnimationStarted(Animator) and onAnimationEnded(Animator) callbacks, in that sequence.
+
+        a1.setStartDelay(20);
+
+        // First start a1's first run.
+        final MyListener normalEndingListener = new MyListener();
+        a1.addListener(normalEndingListener);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(a1.isStarted());
+                assertFalse(normalEndingListener.startCalled);
+                assertFalse(normalEndingListener.endCalled);
+                // Start normally
+                a1.start();
+            }
+        });
+
+        Thread.sleep(a1.getTotalDuration() + POLL_INTERVAL);
+
+        // a1 should have finished by now.
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Call end() on both a1 and a2 without calling start()
+                final MyListener l1 = new MyListener();
+                a1.addListener(l1);
+                final MyListener l2 = new MyListener();
+                a2.addListener(l2);
+
+                assertFalse(a1.isStarted());
+                assertFalse(l1.startCalled);
+                assertFalse(l1.endCalled);
+                assertFalse(a2.isStarted());
+                assertFalse(l2.startCalled);
+                assertFalse(l1.endCalled);
+
+                a1.end();
+                a2.end();
+
+                // Check that both animators' listeners have received the animation callbacks.
+                assertTrue(l1.startCalled);
+                assertTrue(l1.endCalled);
+                assertFalse(a1.isStarted());
+                assertTrue(l1.endTime >= l1.startTime);
+
+                assertTrue(l2.startCalled);
+                assertTrue(l2.endCalled);
+                assertFalse(a2.isStarted());
+                assertTrue(l2.endTime >= l1.startTime);
+            }
+        });
+    }
+
+    @SmallTest
     public void testZeroDuration() throws Throwable {
         // Run two animators with zero duration, with one running forward and the other one
         // backward. Check that the animations start and finish with the correct end fractions.
diff --git a/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java b/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java
index 4c9b00a..dcf2c89 100644
--- a/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java
+++ b/core/tests/coretests/src/android/content/pm/AppsQueryHelperTests.java
@@ -33,7 +33,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mAppsQueryHelper = new AppsQueryHelperTestable(getContext());
+        mAppsQueryHelper = new AppsQueryHelperTestable();
     }
 
     public void testQueryAppsSystemAppsOnly() {
@@ -78,33 +78,20 @@
         assertEqualsIgnoreOrder(Arrays.asList("sys_app1", "sys_app3"), apps);
     }
 
-    public void testQueryAppsDefaultIme() {
-        // Test query default system IMEs
-        List<String> apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_IMES,
+    public void testQueryAppsImes() {
+        // Test query system IMEs
+        List<String> apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_IMES,
                 true, UserHandle.of(UserHandle.myUserId()));
         assertEqualsIgnoreOrder(Arrays.asList("sys_app1"), apps);
 
-        // Test query default IMEs
-        apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_IMES, false,
+        // Test query IMEs
+        apps = mAppsQueryHelper.queryApps(AppsQueryHelper.GET_IMES, false,
                 UserHandle.of(UserHandle.myUserId()));
         assertEqualsIgnoreOrder(Arrays.asList("sys_app1", "app4"), apps);
-
-        // Test that GET_DEFAULT_IMES cannot be used with a user id different from current process
-        try {
-            mAppsQueryHelper.queryApps(AppsQueryHelper.GET_DEFAULT_IMES, false,
-                    UserHandle.of(UserHandle.USER_NULL));
-            fail("queryApps must fail if wrong user was passed");
-        } catch (IllegalArgumentException e) {
-            // OK
-        }
     }
 
     private class AppsQueryHelperTestable extends AppsQueryHelper {
 
-        public AppsQueryHelperTestable(Context context) {
-            super(context);
-        }
-
         @Override
         protected List<ApplicationInfo> getAllApps(int userId) {
             final ApplicationInfo ai1 = new ApplicationInfo();
@@ -145,18 +132,19 @@
         }
 
         @Override
-        protected List<InputMethodInfo> getInputMethodList() {
+        protected List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int userId) {
             final ResolveInfo sysApp1 = new ResolveInfo();
             sysApp1.serviceInfo = new ServiceInfo();
             sysApp1.serviceInfo.packageName = "sys_app1";
             sysApp1.serviceInfo.name = "name";
-            InputMethodInfo imi1 = new InputMethodInfo(sysApp1, false, null, null, 0, true);
+            sysApp1.serviceInfo.applicationInfo = new ApplicationInfo();
+            sysApp1.serviceInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
             final ResolveInfo app4 = new ResolveInfo();
             app4.serviceInfo = new ServiceInfo();
             app4.serviceInfo.packageName = "app4";
             app4.serviceInfo.name = "name";
-            InputMethodInfo imi2 = new InputMethodInfo(app4, false, null, null, 0, true);
-            return Arrays.asList(imi1, imi2);
+            app4.serviceInfo.applicationInfo = new ApplicationInfo();
+            return Arrays.asList(sysApp1, app4);
         }
     }
 
diff --git a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
index 87b3785..3ce45e9 100644
--- a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
+++ b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
@@ -61,11 +61,13 @@
         final int expectedHighlightTextColor = tmpTp.getColor();
         final float expectedHighlightTextSize = tmpTp.getTextSize();
 
-        // Create and wait until SuggestionsPopupWindow is shown.
         final EditText editText = (EditText) activity.findViewById(R.id.textview);
         final Editor editor = editText.getEditorForTesting();
         assertNotNull(editor);
-        activity.runOnUiThread(new Runnable() {
+
+        // Request to show SuggestionsPopupWindow.
+        Runnable showSuggestionWindowRunner = new Runnable() {
+            @Override
             public void run() {
                 SpannableStringBuilder ssb = new SpannableStringBuilder();
                 ssb.append(sampleText);
@@ -78,8 +80,7 @@
                 Selection.setSelection(editText.getText(), singleWordSpanStart, singleWordSpanEnd);
                 editText.onTextContextMenuItem(TextView.ID_REPLACE);
             }
-        });
-        getInstrumentation().waitForIdleSync();
+        };
 
         // In this test, the SuggestionsPopupWindow looks like
         //   abc def ghi
@@ -91,7 +92,8 @@
         // | DELETE        |
         // -----------------
         // *XX* means that XX is highlighted.
-        activity.runOnUiThread(new Runnable() {
+        Runnable popupVaridator = new Runnable() {
+            @Override
             public void run() {
                 Editor.SuggestionsPopupWindow popupWindow =
                         editor.getSuggestionsPopupWindowForTesting();
@@ -155,6 +157,25 @@
                     assertEquals(multiWordSpanEnd, spanned.getSpanEnd(taSpan[0]));
                 }
             }
+        };
+
+        // Show the SuggestionWindow and verify the contents.
+        activity.runOnUiThread(showSuggestionWindowRunner);
+        getInstrumentation().waitForIdleSync();
+        activity.runOnUiThread(popupVaridator);
+
+        // Request to hide the SuggestionPopupWindow and wait until it is hidden.
+        activity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                editText.setText("");
+            }
         });
+        getInstrumentation().waitForIdleSync();
+
+        // Show and verify the contents again.
+        activity.runOnUiThread(showSuggestionWindowRunner);
+        getInstrumentation().waitForIdleSync();
+        activity.runOnUiThread(popupVaridator);
     }
 }
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index c1ccef0..21e3057 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -562,10 +562,11 @@
     <tr>
        <td rowspan="6">Camera</td>
        <td><code>android.hardware.camera</code></td>
-       <td>The application uses the device's camera. If the device supports
-           multiple cameras, the application uses the camera that facing
-           away from the screen.</td>
-       <td></td>
+       <td>The application uses the device's back-facing (main) camera.</td>
+       <td>Devices with only a front-facing camera do not list this feature, so the
+           <code>android.hardware.camera.any</code> feature should be
+           used instead if a camera facing any direction is acceptable for the
+           application.</td>
     </tr>
 <tr>
   <td><code>android.hardware.camera.autofocus</code></td>
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 39d13df..a50c945 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -913,16 +913,26 @@
     protected void onBoundsChange(Rect bounds) {}
 
     /**
-     * Return the intrinsic width of the underlying drawable object.  Returns
-     * -1 if it has no intrinsic width, such as with a solid color.
+     * Returns the drawable's intrinsic width.
+     * <p>
+     * Intrinsic width is the width at which the drawable would like to be laid
+     * out, including any inherent padding. If the drawable has no intrinsic
+     * width, such as a solid color, this method returns -1.
+     *
+     * @return the intrinsic width, or -1 if no intrinsic width
      */
     public int getIntrinsicWidth() {
         return -1;
     }
 
     /**
-     * Return the intrinsic height of the underlying drawable object. Returns
-     * -1 if it has no intrinsic height, such as with a solid color.
+     * Returns the drawable's intrinsic height.
+     * <p>
+     * Intrinsic height is the height at which the drawable would like to be
+     * laid out, including any inherent padding. If the drawable has no
+     * intrinsic height, such as a solid color, this method returns -1.
+     *
+     * @return the intrinsic height, or -1 if no intrinsic height
      */
     public int getIntrinsicHeight() {
         return -1;
@@ -1230,30 +1240,54 @@
      */
     public static abstract class ConstantState {
         /**
-         * Create a new drawable without supplying resources the caller
-         * is running in.  Note that using this means the density-dependent
-         * drawables (like bitmaps) will not be able to update their target
-         * density correctly. One should use {@link #newDrawable(Resources)}
-         * instead to provide a resource.
+         * Creates a new Drawable instance from its constant state.
+         * <p>
+         * <strong>Note:</strong> Using this method means density-dependent
+         * properties, such as pixel dimensions or bitmap images, will not be
+         * updated to match the density of the target display. To ensure
+         * correct scaling, use {@link #newDrawable(Resources)} instead to
+         * provide an appropriate Resources object.
+         *
+         * @return a new drawable object based on this constant state
+         * @see {@link #newDrawable(Resources)}
          */
+        @NonNull
         public abstract Drawable newDrawable();
 
         /**
-         * Create a new Drawable instance from its constant state.  This
-         * must be implemented for drawables that change based on the target
-         * density of their caller (that is depending on whether it is
-         * in compatibility mode).
+         * Creates a new Drawable instance from its constant state using the
+         * specified resources. This method should be implemented for drawables
+         * that have density-dependent properties.
+         * <p>
+         * The default implementation for this method calls through to
+         * {@link #newDrawable()}.
+         *
+         * @param res the resources of the context in which the drawable will
+         *            be displayed
+         * @return a new drawable object based on this constant state
          */
-        public Drawable newDrawable(Resources res) {
+        @NonNull
+        public Drawable newDrawable(@Nullable Resources res) {
             return newDrawable();
         }
 
         /**
-         * Create a new Drawable instance from its constant state. This must be
-         * implemented for drawables that can have a theme applied.
+         * Creates a new Drawable instance from its constant state using the
+         * specified resources and theme. This method should be implemented for
+         * drawables that have theme-dependent properties.
+         * <p>
+         * The default implementation for this method calls through to
+         * {@link #newDrawable(Resources)}.
+         *
+         * @param res the resources of the context in which the drawable will
+         *            be displayed
+         * @param theme the theme of the context in which the drawable will be
+         *              displayed
+         * @return a new drawable object based on this constant state
          */
-        public Drawable newDrawable(Resources res, Theme theme) {
-            return newDrawable(null);
+        @NonNull
+        public Drawable newDrawable(@Nullable Resources res, @Nullable Theme theme) {
+            return newDrawable(res);
         }
 
         /**
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index b2044e1..d05c66a 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -144,7 +144,7 @@
             mAlpha = alpha;
             if (mCurrDrawable != null) {
                 if (mEnterAnimationEnd == 0) {
-                    mCurrDrawable.mutate().setAlpha(alpha);
+                    mCurrDrawable.setAlpha(alpha);
                 } else {
                     animate(false);
                 }
@@ -162,7 +162,7 @@
         if (mDrawableContainerState.mDither != dither) {
             mDrawableContainerState.mDither = dither;
             if (mCurrDrawable != null) {
-                mCurrDrawable.mutate().setDither(mDrawableContainerState.mDither);
+                mCurrDrawable.setDither(mDrawableContainerState.mDither);
             }
         }
     }
@@ -175,7 +175,7 @@
             mDrawableContainerState.mColorFilter = colorFilter;
 
             if (mCurrDrawable != null) {
-                mCurrDrawable.mutate().setColorFilter(colorFilter);
+                mCurrDrawable.setColorFilter(colorFilter);
             }
         }
     }
@@ -188,7 +188,7 @@
             mDrawableContainerState.mTintList = tint;
 
             if (mCurrDrawable != null) {
-                mCurrDrawable.mutate().setTintList(tint);
+                mCurrDrawable.setTintList(tint);
             }
         }
     }
@@ -201,7 +201,7 @@
             mDrawableContainerState.mTintMode = tintMode;
 
             if (mCurrDrawable != null) {
-                mCurrDrawable.mutate().setTintMode(tintMode);
+                mCurrDrawable.setTintMode(tintMode);
             }
         }
     }
@@ -244,7 +244,7 @@
         if (mDrawableContainerState.mAutoMirrored != mirrored) {
             mDrawableContainerState.mAutoMirrored = mirrored;
             if (mCurrDrawable != null) {
-                mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+                mCurrDrawable.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
             }
         }
     }
@@ -266,7 +266,7 @@
         if (mCurrDrawable != null) {
             mCurrDrawable.jumpToCurrentState();
             if (mHasAlpha) {
-                mCurrDrawable.mutate().setAlpha(mAlpha);
+                mCurrDrawable.setAlpha(mAlpha);
             }
         }
         if (mExitAnimationEnd != 0) {
@@ -499,8 +499,6 @@
      * @param d The drawable to initialize.
      */
     private void initializeDrawableForDisplay(Drawable d) {
-        d.mutate();
-
         if (mDrawableContainerState.mEnterFadeDuration <= 0 && mHasAlpha) {
             d.setAlpha(mAlpha);
         }
@@ -540,13 +538,12 @@
         if (mCurrDrawable != null) {
             if (mEnterAnimationEnd != 0) {
                 if (mEnterAnimationEnd <= now) {
-                    mCurrDrawable.mutate().setAlpha(mAlpha);
+                    mCurrDrawable.setAlpha(mAlpha);
                     mEnterAnimationEnd = 0;
                 } else {
                     int animAlpha = (int)((mEnterAnimationEnd-now)*255)
                             / mDrawableContainerState.mEnterFadeDuration;
-                    if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha);
-                    mCurrDrawable.mutate().setAlpha(((255-animAlpha)*mAlpha)/255);
+                    mCurrDrawable.setAlpha(((255-animAlpha)*mAlpha)/255);
                     animating = true;
                 }
             }
@@ -563,8 +560,7 @@
                 } else {
                     int animAlpha = (int)((mExitAnimationEnd-now)*255)
                             / mDrawableContainerState.mExitFadeDuration;
-                    if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha);
-                    mLastDrawable.mutate().setAlpha((animAlpha*mAlpha)/255);
+                    mLastDrawable.setAlpha((animAlpha*mAlpha)/255);
                     animating = true;
                 }
             }
@@ -656,7 +652,7 @@
         int mChangingConfigurations;
         int mChildrenChangingConfigurations;
 
-        SparseArray<ConstantStateFuture> mDrawableFutures;
+        SparseArray<ConstantState> mDrawableFutures;
         Drawable[] mDrawables;
         int mNumChildren;
 
@@ -757,7 +753,7 @@
                 mDrawables = new Drawable[origDr.length];
                 mNumChildren = orig.mNumChildren;
 
-                final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures;
+                final SparseArray<ConstantState> origDf = orig.mDrawableFutures;
                 if (origDf != null) {
                     mDrawableFutures = origDf.clone();
                 } else {
@@ -770,8 +766,9 @@
                 final int N = mNumChildren;
                 for (int i = 0; i < N; i++) {
                     if (origDr[i] != null) {
-                        if (origDr[i].getConstantState() != null) {
-                            mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
+                        final ConstantState cs = origDr[i].getConstantState();
+                        if (cs != null) {
+                            mDrawableFutures.put(i, cs);
                         } else {
                             mDrawables[i] = origDr[i];
                         }
@@ -815,18 +812,26 @@
             return mDrawables.length;
         }
 
-        private final void createAllFutures() {
+        private void createAllFutures() {
             if (mDrawableFutures != null) {
                 final int futureCount = mDrawableFutures.size();
                 for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) {
                     final int index = mDrawableFutures.keyAt(keyIndex);
-                    mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this);
+                    final ConstantState cs = mDrawableFutures.valueAt(keyIndex);
+                    mDrawables[index] = prepareDrawable(cs.newDrawable(mSourceRes));
                 }
 
                 mDrawableFutures = null;
             }
         }
 
+        private Drawable prepareDrawable(Drawable child) {
+            child.setLayoutDirection(mLayoutDirection);
+            child.setCallback(mOwner);
+            child = child.mutate();
+            return child;
+        }
+
         public final int getChildCount() {
             return mNumChildren;
         }
@@ -851,7 +856,8 @@
             if (mDrawableFutures != null) {
                 final int keyIndex = mDrawableFutures.indexOfKey(index);
                 if (keyIndex >= 0) {
-                    final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this);
+                    final ConstantState cs = mDrawableFutures.valueAt(keyIndex);
+                    final Drawable prepared = prepareDrawable(cs.newDrawable(mSourceRes));
                     mDrawables[index] = prepared;
                     mDrawableFutures.removeAt(keyIndex);
                     if (mDrawableFutures.size() == 0) {
@@ -938,7 +944,7 @@
                         return true;
                     }
                 } else {
-                    final ConstantStateFuture future = mDrawableFutures.get(i);
+                    final ConstantState future = mDrawableFutures.get(i);
                     if (future != null && future.canApplyTheme()) {
                         return true;
                     }
@@ -1173,49 +1179,6 @@
             }
             return pixelCount;
         }
-
-        /**
-         * Class capable of cloning a Drawable from another Drawable's
-         * ConstantState.
-         */
-        private static class ConstantStateFuture {
-            private final ConstantState mConstantState;
-
-            private ConstantStateFuture(Drawable source) {
-                mConstantState = source.getConstantState();
-            }
-
-            /**
-             * Obtains and prepares the Drawable represented by this future.
-             *
-             * @param state the container into which this future will be placed
-             * @return a prepared Drawable
-             */
-            public Drawable get(DrawableContainerState state) {
-                final Drawable result;
-                if (state.mSourceRes == null) {
-                    result = mConstantState.newDrawable();
-                } else {
-                    result = mConstantState.newDrawable(state.mSourceRes);
-                }
-                result.setLayoutDirection(state.mLayoutDirection);
-                result.setCallback(state.mOwner);
-
-                if (state.mMutated) {
-                    result.mutate();
-                }
-
-                return result;
-            }
-
-            /**
-             * Whether the constant state wrapped by this future can apply a
-             * theme.
-             */
-            public boolean canApplyTheme() {
-                return mConstantState.canApplyTheme();
-            }
-        }
     }
 
     protected void setConstantState(DrawableContainerState state) {
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 927b9c9..36d4272 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -222,12 +222,20 @@
 
     @Override
     public int getIntrinsicWidth() {
-        return getDrawable().getIntrinsicWidth() + mState.mInsetLeft + mState.mInsetRight;
+        final int childWidth = getDrawable().getIntrinsicWidth();
+        if (childWidth < 0) {
+            return -1;
+        }
+        return childWidth + mState.mInsetLeft + mState.mInsetRight;
     }
 
     @Override
     public int getIntrinsicHeight() {
-        return getDrawable().getIntrinsicHeight() + mState.mInsetTop + mState.mInsetBottom;
+        final int childHeight = getDrawable().getIntrinsicHeight();
+        if (childHeight < 0) {
+            return -1;
+        }
+        return childHeight + mState.mInsetTop + mState.mInsetBottom;
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 1ede105..651b453 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1601,8 +1601,10 @@
                 insetR = r.mInsetE == UNDEFINED_INSET ? r.mInsetR : r.mInsetE;
             }
 
+            // Don't apply padding and insets for children that don't have
+            // an intrinsic dimension.
             final int minWidth = r.mWidth < 0 ? r.mDrawable.getIntrinsicWidth() : r.mWidth;
-            final int w = minWidth + insetL + insetR + padL + padR;
+            final int w = minWidth < 0 ? -1 : minWidth + insetL + insetR + padL + padR;
             if (w > width) {
                 width = w;
             }
@@ -1631,8 +1633,10 @@
                 continue;
             }
 
+            // Don't apply padding and insets for children that don't have
+            // an intrinsic dimension.
             final int minHeight = r.mHeight < 0 ? r.mDrawable.getIntrinsicHeight() : r.mHeight;
-            final int h = minHeight + r.mInsetT + r.mInsetB + padT + padB;
+            final int h = minHeight < 0 ? -1 : minHeight + r.mInsetT + r.mInsetB + padT + padB;
             if (h > height) {
                 height = h;
             }
diff --git a/graphics/java/android/graphics/drawable/RippleComponent.java b/graphics/java/android/graphics/drawable/RippleComponent.java
index 2d378c6..e83513c 100644
--- a/graphics/java/android/graphics/drawable/RippleComponent.java
+++ b/graphics/java/android/graphics/drawable/RippleComponent.java
@@ -20,6 +20,7 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.util.DisplayMetrics;
 import android.view.DisplayListCanvas;
 import android.view.RenderNodeAnimator;
 
@@ -50,7 +51,7 @@
     protected float mTargetRadius;
 
     /** Screen density used to adjust pixel-based constants. */
-    protected float mDensity;
+    protected float mDensityScale;
 
     /**
      * If set, force all ripple animations to not run on RenderThread, even if it would be
@@ -71,7 +72,7 @@
         }
     }
 
-    public final void setup(float maxRadius, float density) {
+    public final void setup(float maxRadius, int densityDpi) {
         if (maxRadius >= 0) {
             mHasMaxRadius = true;
             mTargetRadius = maxRadius;
@@ -79,7 +80,7 @@
             mTargetRadius = getTargetRadius(mBounds);
         }
 
-        mDensity = density;
+        mDensityScale = densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
 
         onTargetRadiusChanged(mTargetRadius);
     }
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 52e7f24..aaab529 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -160,7 +160,7 @@
     private Paint mRipplePaint;
 
     /** Target density of the display into which ripples are drawn. */
-    private float mDensity = 1.0f;
+    private int mDensity;
 
     /** Whether bounds are being overridden. */
     private boolean mOverrideBounds;
@@ -544,8 +544,7 @@
             mBackground = new RippleBackground(this, mHotspotBounds, mForceSoftware);
         }
 
-        final float densityScale = mState.mDensity * DisplayMetrics.DENSITY_DEFAULT_SCALE;
-        mBackground.setup(mState.mMaxRadius, densityScale);
+        mBackground.setup(mState.mMaxRadius, mDensity);
         mBackground.enter(focused);
     }
 
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index c660846..829733e 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -168,7 +168,7 @@
         }
 
         final int duration = (int)
-                (1000 * Math.sqrt(mTargetRadius / WAVE_TOUCH_DOWN_ACCELERATION * mDensity) + 0.5);
+                (1000 * Math.sqrt(mTargetRadius / WAVE_TOUCH_DOWN_ACCELERATION * mDensityScale) + 0.5);
 
         final ObjectAnimator tweenRadius = ObjectAnimator.ofFloat(this, TWEEN_RADIUS, 1);
         tweenRadius.setAutoCancel(true);
@@ -204,7 +204,7 @@
     private int getRadiusExitDuration() {
         final float remainingRadius = mTargetRadius - getCurrentRadius();
         return (int) (1000 * Math.sqrt(remainingRadius / (WAVE_TOUCH_UP_ACCELERATION
-                + WAVE_TOUCH_DOWN_ACCELERATION) * mDensity) + 0.5);
+                + WAVE_TOUCH_DOWN_ACCELERATION) * mDensityScale) + 0.5);
     }
 
     private float getCurrentRadius() {
diff --git a/libs/androidfw/tests/AppAsLib_test.cpp b/libs/androidfw/tests/AppAsLib_test.cpp
index bdb0c3d..8489acf 100644
--- a/libs/androidfw/tests/AppAsLib_test.cpp
+++ b/libs/androidfw/tests/AppAsLib_test.cpp
@@ -16,7 +16,6 @@
 
 #include <androidfw/ResourceTypes.h>
 
-#include "data/basic/R.h"
 #include "data/appaslib/R.h"
 
 #include <gtest/gtest.h>
@@ -25,29 +24,45 @@
 
 namespace {
 
-#include "data/basic/basic_arsc.h"
+#include "data/appaslib/appaslib_arsc.h"
+#include "data/appaslib/appaslib_lib_arsc.h"
 
+// This tests the app resources loaded as app.
 TEST(AppAsLibTest, loadedAsApp) {
   ResTable table;
-  ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len));
+  ASSERT_EQ(NO_ERROR, table.add(appaslib_arsc, appaslib_arsc_len));
 
   Res_value val;
-  ssize_t block = table.getResource(base::R::integer::number2, &val);
+  ssize_t block = table.getResource(appaslib::R::app::integer::number1, &val);
   ASSERT_GE(block, 0);
   ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
-  ASSERT_EQ(base::R::array::integerArray1, val.data);
+  ASSERT_EQ(appaslib::R::app::array::integerArray1, val.data);
 }
 
+// This tests the app resources loaded as shared-lib.
 TEST(AppAsLibTest, loadedAsSharedLib) {
   ResTable table;
   // Load as shared library.
-  ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len, NULL, 0, -1, false, true));
+  ASSERT_EQ(NO_ERROR, table.add(appaslib_arsc, appaslib_arsc_len, NULL, 0, -1, false, true));
 
   Res_value val;
-  ssize_t block = table.getResource(appaslib::R::integer::number2, &val);
+  ssize_t block = table.getResource(appaslib::R::lib::integer::number1, &val);
   ASSERT_GE(block, 0);
   ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
-  ASSERT_EQ(appaslib::R::array::integerArray1, val.data);
+  ASSERT_EQ(appaslib::R::lib::array::integerArray1, val.data);
+}
+
+// This tests the shared-lib loaded with appAsLib as true.
+TEST(AppAsLibTest, loadedSharedLib) {
+  ResTable table;
+  // Load shared library with appAsLib as true.
+  ASSERT_EQ(NO_ERROR, table.add(appaslib_lib_arsc, appaslib_lib_arsc_len, NULL, 0, -1, false, true));
+
+  Res_value val;
+  ssize_t block = table.getResource(appaslib::R::lib::integer::number1, &val);
+  ASSERT_GE(block, 0);
+  ASSERT_EQ(Res_value::TYPE_REFERENCE, val.dataType);
+  ASSERT_EQ(appaslib::R::lib::array::integerArray1, val.data);
 }
 
 }
diff --git a/packages/DocumentsUI/res/drawable/item_doc_grid_overlay.xml b/libs/androidfw/tests/data/appaslib/AndroidManifest.xml
similarity index 72%
copy from packages/DocumentsUI/res/drawable/item_doc_grid_overlay.xml
copy to libs/androidfw/tests/data/appaslib/AndroidManifest.xml
index 3f50fb9..e00045b 100644
--- a/packages/DocumentsUI/res/drawable/item_doc_grid_overlay.xml
+++ b/libs/androidfw/tests/data/appaslib/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.test.basic">
+    <application>
+    </application>
+</manifest>
diff --git a/libs/androidfw/tests/data/appaslib/R.h b/libs/androidfw/tests/data/appaslib/R.h
index f89d4bf..3af921a 100644
--- a/libs/androidfw/tests/data/appaslib/R.h
+++ b/libs/androidfw/tests/data/appaslib/R.h
@@ -19,19 +19,33 @@
 
 namespace appaslib {
 namespace R {
-
+namespace lib {
 namespace integer {
     enum {
-        number2     = 0x02040001,   // default
+        number1     = 0x02020000,   // default
     };
 }
 
 namespace array {
     enum {
-        integerArray1 = 0x02060000,   // default
+        integerArray1 = 0x02030000,   // default
+    };
+}
+} // namespace lib
+
+namespace app {
+namespace integer {
+    enum {
+        number1     = 0x7f020000,     // default
     };
 }
 
+namespace array {
+    enum {
+        integerArray1 = 0x7f030000,   // default
+    };
+}
+} // namespace app
 } // namespace R
 } // namespace appaslib
 
diff --git a/libs/androidfw/tests/data/appaslib/appaslib_arsc.h b/libs/androidfw/tests/data/appaslib/appaslib_arsc.h
new file mode 100644
index 0000000..be176ab
--- /dev/null
+++ b/libs/androidfw/tests/data/appaslib/appaslib_arsc.h
@@ -0,0 +1,68 @@
+unsigned char appaslib_arsc[] = {
+  0x02, 0x00, 0x0c, 0x00, 0x04, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xdc, 0x02, 0x00, 0x00,
+  0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,
+  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,
+  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x54, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00,
+  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00,
+  0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00,
+  0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00,
+  0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x54, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x6d, 0x00,
+  0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0d, 0x00,
+  0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00,
+  0x72, 0x00, 0x41, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00,
+  0x31, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x48, 0x00, 0x5c, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
+  0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x7f,
+  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x48, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x4c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,
+  0x03, 0x00, 0x00, 0x00
+};
+unsigned int appaslib_arsc_len = 772;
diff --git a/libs/androidfw/tests/data/appaslib/appaslib_lib_arsc.h b/libs/androidfw/tests/data/appaslib/appaslib_lib_arsc.h
new file mode 100644
index 0000000..099285a
--- /dev/null
+++ b/libs/androidfw/tests/data/appaslib/appaslib_lib_arsc.h
@@ -0,0 +1,68 @@
+unsigned char appaslib_lib_arsc[] = {
+  0x02, 0x00, 0x0c, 0x00, 0x04, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xdc, 0x02, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00,
+  0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00,
+  0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+  0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x54, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00,
+  0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00,
+  0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00,
+  0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00,
+  0x79, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x54, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x6d, 0x00,
+  0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0d, 0x00,
+  0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00,
+  0x72, 0x00, 0x41, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00,
+  0x31, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x48, 0x00, 0x5c, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
+  0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x00,
+  0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x48, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x4c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10,
+  0x03, 0x00, 0x00, 0x00
+};
+unsigned int appaslib_lib_arsc_len = 772;
diff --git a/libs/androidfw/tests/data/appaslib/build b/libs/androidfw/tests/data/appaslib/build
new file mode 100755
index 0000000..e4bd88b
--- /dev/null
+++ b/libs/androidfw/tests/data/appaslib/build
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# 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.
+#
+
+PATH_TO_FRAMEWORK_RES=$(gettop)/prebuilts/sdk/current/android.jar
+
+aapt package -M AndroidManifest.xml -S res -I $PATH_TO_FRAMEWORK_RES -F bundle.apk -f && \
+unzip bundle.apk resources.arsc && \
+mv resources.arsc appaslib.arsc && \
+xxd -i appaslib.arsc > appaslib_arsc.h && \
+aapt package -M AndroidManifest.xml -S res -I $PATH_TO_FRAMEWORK_RES -F bundle.apk -f --shared-lib && \
+unzip bundle.apk resources.arsc && \
+mv resources.arsc appaslib_lib.arsc && \
+xxd -i appaslib_lib.arsc > appaslib_lib_arsc.h \
+
diff --git a/core/res/res/layout/docked_stack_divider.xml b/libs/androidfw/tests/data/appaslib/res/values/values.xml
similarity index 72%
rename from core/res/res/layout/docked_stack_divider.xml
rename to libs/androidfw/tests/data/appaslib/res/values/values.xml
index aa6e68d..39b99a6 100644
--- a/core/res/res/layout/docked_stack_divider.xml
+++ b/libs/androidfw/tests/data/appaslib/res/values/values.xml
@@ -14,8 +14,11 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="@dimen/docked_stack_divider_thickness"
-        android:layout_height="match_parent"
-        android:background="@android:color/black"
-        />
+<resources>
+    <integer name="number1">@array/integerArray1</integer>
+    <integer-array name="integerArray1">
+        <item>1</item>
+        <item>2</item>
+        <item>3</item>
+    </integer-array>
+</resources>
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 603caf1..8565372 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -9,6 +9,7 @@
     font/Font.cpp \
     renderstate/Blend.cpp \
     renderstate/MeshState.cpp \
+    renderstate/OffscreenBufferPool.cpp \
     renderstate/PixelBufferState.cpp \
     renderstate/RenderState.cpp \
     renderstate/Scissor.cpp \
@@ -39,6 +40,7 @@
     DamageAccumulator.cpp \
     DeferredDisplayList.cpp \
     DeferredLayerUpdater.cpp \
+    DeviceInfo.cpp \
     DisplayList.cpp \
     DisplayListCanvas.cpp \
     Dither.cpp \
@@ -63,6 +65,7 @@
     PatchCache.cpp \
     PathCache.cpp \
     PathTessellator.cpp \
+    PathParser.cpp \
     PixelBuffer.cpp \
     Program.cpp \
     ProgramCache.cpp \
@@ -81,6 +84,7 @@
     TextDropShadowCache.cpp \
     Texture.cpp \
     TextureCache.cpp \
+    VectorDrawablePath.cpp \
     protos/hwui.proto
 
 hwui_cflags := \
@@ -202,15 +206,20 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
 LOCAL_STATIC_LIBRARIES := libhwui_static_null_gpu
-LOCAL_CFLAGS := $(hwui_cflags)
+LOCAL_CFLAGS := \
+        $(hwui_cflags) \
+        -DHWUI_NULL_GPU
 
 LOCAL_SRC_FILES += \
     unit_tests/CanvasStateTests.cpp \
     unit_tests/ClipAreaTests.cpp \
     unit_tests/DamageAccumulatorTests.cpp \
+    unit_tests/DeviceInfoTests.cpp \
     unit_tests/FatVectorTests.cpp \
     unit_tests/LayerUpdateQueueTests.cpp \
     unit_tests/LinearAllocatorTests.cpp \
+    unit_tests/PathParserTests.cpp \
+    unit_tests/OffscreenBufferPoolTests.cpp \
     unit_tests/StringUtilsTests.cpp
 
 ifeq (true, $(HWUI_NEW_OPS))
@@ -270,6 +279,7 @@
 LOCAL_SRC_FILES += \
     microbench/DisplayListCanvasBench.cpp \
     microbench/LinearAllocatorBench.cpp \
+    microbench/PathParserBench.cpp \
     microbench/ShadowBench.cpp
 
 ifeq (true, $(HWUI_NEW_OPS))
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 2fca5ea..d2d3285 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -19,104 +19,29 @@
 #include "Caches.h"
 #include "Glop.h"
 #include "GlopBuilder.h"
+#include "renderstate/OffscreenBufferPool.h"
 #include "renderstate/RenderState.h"
-#include "utils/FatVector.h"
 #include "utils/GLUtils.h"
+#include "VertexBuffer.h"
 
 namespace android {
 namespace uirenderer {
 
 ////////////////////////////////////////////////////////////////////////////////
-// OffscreenBuffer
-////////////////////////////////////////////////////////////////////////////////
-
-OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches,
-        uint32_t textureWidth, uint32_t textureHeight,
-        uint32_t viewportWidth, uint32_t viewportHeight)
-        : renderState(renderState)
-        , viewportWidth(viewportWidth)
-        , viewportHeight(viewportHeight)
-        , texture(caches) {
-    texture.width = textureWidth;
-    texture.height = textureHeight;
-
-    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);
-    // 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);
-}
-
-void OffscreenBuffer::updateMeshFromRegion() {
-    // avoid T-junctions as they cause artifacts in between the resultant
-    // geometry when complex transforms occur.
-    // TODO: generate the safeRegion only if necessary based on drawing transform
-    Region safeRegion = Region::createTJunctionFreeRegion(region);
-
-    size_t count;
-    const android::Rect* rects = safeRegion.getArray(&count);
-
-    const float texX = 1.0f / float(viewportWidth);
-    const float texY = 1.0f / float(viewportHeight);
-
-    FatVector<TextureVertex, 64> meshVector(count * 4); // uses heap if more than 64 vertices needed
-    TextureVertex* mesh = &meshVector[0];
-    for (size_t i = 0; i < count; i++) {
-        const android::Rect* r = &rects[i];
-
-        const float u1 = r->left * texX;
-        const float v1 = (viewportHeight - r->top) * texY;
-        const float u2 = r->right * texX;
-        const float v2 = (viewportHeight - r->bottom) * texY;
-
-        TextureVertex::set(mesh++, r->left, r->top, u1, v1);
-        TextureVertex::set(mesh++, r->right, r->top, u2, v1);
-        TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
-        TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
-    }
-    elementCount = count * 6;
-    renderState.meshState().genOrUpdateMeshBuffer(&vbo,
-            sizeof(TextureVertex) * count * 4,
-            &meshVector[0],
-            GL_DYNAMIC_DRAW); // TODO: GL_STATIC_DRAW if savelayer
-}
-
-OffscreenBuffer::~OffscreenBuffer() {
-    texture.deleteTexture();
-    renderState.meshState().deleteMeshBuffer(vbo);
-    elementCount = 0;
-    vbo = 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // BakedOpRenderer
 ////////////////////////////////////////////////////////////////////////////////
 
-OffscreenBuffer* BakedOpRenderer::createOffscreenBuffer(RenderState& renderState,
-        uint32_t width, uint32_t height) {
-    // TODO: get from cache!
-    return new OffscreenBuffer(renderState, Caches::getInstance(), width, height, width, height);
-}
-
-void BakedOpRenderer::destroyOffscreenBuffer(OffscreenBuffer* offscreenBuffer) {
-    // TODO: return texture/offscreenbuffer to cache!
-    delete offscreenBuffer;
-}
-
-OffscreenBuffer* BakedOpRenderer::createLayer(uint32_t width, uint32_t height) {
+OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) {
     LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
 
-    OffscreenBuffer* buffer = createOffscreenBuffer(mRenderState, width, height);
-    startLayer(buffer);
+    OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
+    startRepaintLayer(buffer, Rect(width, height));
     return buffer;
 }
 
-void BakedOpRenderer::startLayer(OffscreenBuffer* offscreenBuffer) {
+void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) {
+    LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
+
     mRenderTarget.offscreenBuffer = offscreenBuffer;
 
     // create and bind framebuffer
@@ -130,12 +55,10 @@
     LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
             "framebuffer incomplete!");
 
-    // Clear the FBO
-    mRenderState.scissor().setEnabled(false);
-    glClear(GL_COLOR_BUFFER_BIT);
-
     // Change the viewport & ortho projection
     setViewport(offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight);
+
+    clearColorBuffer(repaintRect);
 }
 
 void BakedOpRenderer::endLayer() {
@@ -149,16 +72,13 @@
     mRenderTarget.frameBufferId = -1;
 }
 
-void BakedOpRenderer::startFrame(uint32_t width, uint32_t height) {
+void BakedOpRenderer::startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) {
     mRenderState.bindFramebuffer(0);
     setViewport(width, height);
     mCaches.clearGarbage();
 
     if (!mOpaque) {
-        // TODO: partial invalidate!
-        mRenderState.scissor().setEnabled(false);
-        glClear(GL_COLOR_BUFFER_BIT);
-        mHasDrawn = true;
+        clearColorBuffer(repaintRect);
     }
 }
 
@@ -188,6 +108,20 @@
     mRenderState.blend().syncEnabled();
 }
 
+void BakedOpRenderer::clearColorBuffer(const Rect& rect) {
+    if (Rect(mRenderTarget.viewportWidth, mRenderTarget.viewportHeight).contains(rect)) {
+        // Full viewport is being cleared - disable scissor
+        mRenderState.scissor().setEnabled(false);
+    } else {
+        // Requested rect is subset of viewport - scissor to it to avoid over-clearing
+        mRenderState.scissor().setEnabled(true);
+        mRenderState.scissor().set(rect.left, mRenderTarget.viewportHeight - rect.bottom,
+                rect.getWidth(), rect.getHeight());
+    }
+    glClear(GL_COLOR_BUFFER_BIT);
+    if (!mRenderTarget.frameBufferId) mHasDrawn = true;
+}
+
 Texture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) {
     Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
     if (!texture) {
@@ -211,7 +145,7 @@
         mRenderTarget.offscreenBuffer->region.orSelf(dirty);
     }
     mRenderState.render(glop, mRenderTarget.orthoMatrix);
-    mHasDrawn = true;
+    if (!mRenderTarget.frameBufferId) mHasDrawn = true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -261,6 +195,69 @@
     renderer.renderGlop(state, glop);
 }
 
+namespace VertexBufferRenderFlags {
+    enum {
+        Offset = 0x1,
+        ShadowInterp = 0x2,
+    };
+}
+
+static void renderVertexBuffer(BakedOpRenderer& renderer, const BakedOpState& state,
+        const VertexBuffer& vertexBuffer, float translateX, float translateY,
+        SkPaint& paint, int vertexBufferRenderFlags) {
+    if (CC_LIKELY(vertexBuffer.getVertexCount())) {
+        bool shadowInterp = vertexBufferRenderFlags & VertexBufferRenderFlags::ShadowInterp;
+        const int transformFlags = TransformFlags::OffsetByFudgeFactor;
+        Glop glop;
+        GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+                .setRoundRectClipState(state.roundRectClipState)
+                .setMeshVertexBuffer(vertexBuffer, shadowInterp)
+                .setFillPaint(paint, state.alpha)
+                .setTransform(state.computedState.transform, transformFlags)
+                .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds())
+                .build();
+        renderer.renderGlop(state, glop);
+    }
+}
+
+static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, float casterAlpha,
+        const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer) {
+    SkPaint paint;
+    paint.setAntiAlias(true); // want to use AlphaVertex
+
+    // The caller has made sure casterAlpha > 0.
+    uint8_t ambientShadowAlpha = renderer.getLightInfo().ambientShadowAlpha;
+    if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
+        ambientShadowAlpha = Properties::overrideAmbientShadowStrength;
+    }
+    if (ambientShadowVertexBuffer && ambientShadowAlpha > 0) {
+        paint.setAlpha((uint8_t)(casterAlpha * ambientShadowAlpha));
+        renderVertexBuffer(renderer, state, *ambientShadowVertexBuffer, 0, 0,
+                paint, VertexBufferRenderFlags::ShadowInterp);
+    }
+
+    uint8_t spotShadowAlpha = renderer.getLightInfo().spotShadowAlpha;
+    if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
+        spotShadowAlpha = Properties::overrideSpotShadowStrength;
+    }
+    if (spotShadowVertexBuffer && spotShadowAlpha > 0) {
+        paint.setAlpha((uint8_t)(casterAlpha * spotShadowAlpha));
+        renderVertexBuffer(renderer, state, *spotShadowVertexBuffer, 0, 0,
+                paint, VertexBufferRenderFlags::ShadowInterp);
+    }
+}
+
+void BakedOpDispatcher::onShadowOp(BakedOpRenderer& renderer, const ShadowOp& op, const BakedOpState& state) {
+    TessellationCache::vertexBuffer_pair_t buffers;
+    renderer.caches().tessellationCache.getShadowBuffers(&state.computedState.transform,
+            op.localClipRect, op.casterAlpha >= 1.0f, op.casterPath,
+            &op.shadowMatrixXY, &op.shadowMatrixZ,
+            op.lightCenter, renderer.getLightInfo().lightRadius,
+            buffers);
+
+    renderShadow(renderer, state, op.casterAlpha, buffers.first, buffers.second);
+}
+
 void BakedOpDispatcher::onSimpleRectsOp(BakedOpRenderer& renderer, const SimpleRectsOp& op, const BakedOpState& state) {
     Glop glop;
     GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
@@ -291,7 +288,7 @@
     renderer.renderGlop(state, glop);
 
     if (op.destroy) {
-        BakedOpRenderer::destroyOffscreenBuffer(buffer);
+        renderer.renderState().layerPool().putOrDelete(buffer);
     }
 }
 
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index aa1e67d..29f9a6f 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -29,33 +29,6 @@
 class RenderState;
 
 /**
- * Lightweight alternative to Layer. Owns the persistent state of an offscreen render target, and
- * encompasses enough information to draw it back on screen (minus paint properties, which are held
- * by LayerOp).
- */
-class OffscreenBuffer {
-public:
-    OffscreenBuffer(RenderState& renderState, Caches& caches,
-            uint32_t textureWidth, uint32_t textureHeight,
-            uint32_t viewportWidth, uint32_t viewportHeight);
-    ~OffscreenBuffer();
-
-    // must be called prior to rendering, to construct/update vertex buffer
-    void updateMeshFromRegion();
-
-    RenderState& renderState;
-    uint32_t viewportWidth;
-    uint32_t viewportHeight;
-    Texture texture;
-
-    // Portion of offscreen buffer that has been drawn to. Used to minimize drawing area when
-    // drawing back to screen / parent FBO.
-    Region region;
-    GLsizei elementCount = 0;
-    GLuint vbo = 0;
-};
-
-/**
  * Main rendering manager for a collection of work - one frame + any contained FBOs.
  *
  * Manages frame and FBO lifecycle, binding the GL framebuffer as appropriate. This is the only
@@ -66,31 +39,39 @@
  */
 class BakedOpRenderer {
 public:
-    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque)
+    /**
+     * 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;
+    };
+
+    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, const LightInfo& lightInfo)
             : mRenderState(renderState)
             , mCaches(caches)
-            , mOpaque(opaque) {
+            , mOpaque(opaque)
+            , mLightInfo(lightInfo) {
     }
 
-    static OffscreenBuffer* createOffscreenBuffer(RenderState& renderState,
-            uint32_t width, uint32_t height);
-    static void destroyOffscreenBuffer(OffscreenBuffer*);
-
     RenderState& renderState() { return mRenderState; }
     Caches& caches() { return mCaches; }
 
-    void startFrame(uint32_t width, uint32_t height);
+    void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect);
     void endFrame();
-    OffscreenBuffer* createLayer(uint32_t width, uint32_t height);
-    void startLayer(OffscreenBuffer* offscreenBuffer);
+    OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
+    void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect);
     void endLayer();
 
     Texture* getTexture(const SkBitmap* bitmap);
+    const LightInfo& getLightInfo() { return mLightInfo; }
 
     void renderGlop(const BakedOpState& state, const Glop& glop);
     bool didDraw() { return mHasDrawn; }
 private:
     void setViewport(uint32_t width, uint32_t height);
+    void clearColorBuffer(const Rect& clearRect);
 
     RenderState& mRenderState;
     Caches& mCaches;
@@ -106,6 +87,8 @@
         uint32_t viewportHeight = 0;
         Matrix4 orthoMatrix;
     } mRenderTarget;
+
+    const LightInfo mLightInfo;
 };
 
 /**
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
index ddb8c84..9a40c3b 100644
--- a/libs/hwui/BakedOpState.h
+++ b/libs/hwui/BakedOpState.h
@@ -89,6 +89,21 @@
          *         and early return null in one place.
          */
     }
+
+    /**
+     * Constructor for unbounded ops without transform/clip (namely shadows)
+     *
+     * Since the op doesn't have known bounds, we conservatively set the mapped bounds
+     * to the current clipRect, and clipSideFlags to Full.
+     */
+    ResolvedRenderState(const Snapshot& snapshot) {
+        transform = *snapshot.transform;
+        clipRect = snapshot.getRenderTargetClip();
+        clippedBounds = clipRect;
+        transform.mapRect(clippedBounds);
+        clipSideFlags = OpClipSideFlags::Full;
+    }
+
     Matrix4 transform;
     Rect clipRect;
     int clipSideFlags = 0;
@@ -104,8 +119,7 @@
 public:
     static BakedOpState* tryConstruct(LinearAllocator& allocator,
             const Snapshot& snapshot, const RecordedOp& recordedOp) {
-        BakedOpState* bakedOp = new (allocator) BakedOpState(
-                snapshot, recordedOp);
+        BakedOpState* bakedOp = new (allocator) BakedOpState(snapshot, recordedOp);
         if (bakedOp->computedState.clippedBounds.isEmpty()) {
             // bounds are empty, so op is rejected
             allocator.rewindIfLastAlloc(bakedOp);
@@ -114,6 +128,14 @@
         return bakedOp;
     }
 
+    static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator,
+            const Snapshot& snapshot, const ShadowOp* shadowOpPtr) {
+        if (snapshot.getRenderTargetClip().isEmpty()) return nullptr;
+
+        // clip isn't empty, so construct the op
+        return new (allocator) BakedOpState(snapshot, shadowOpPtr);
+    }
+
     static void* operator new(size_t size, LinearAllocator& allocator) {
         return allocator.alloc(size);
     }
@@ -134,6 +156,13 @@
             , roundRectClipState(snapshot.roundRectClipState)
             , projectionPathMask(snapshot.projectionPathMask)
             , op(&recordedOp) {}
+
+    BakedOpState(const Snapshot& snapshot, const ShadowOp* shadowOpPtr)
+            : computedState(snapshot)
+            , alpha(snapshot.alpha)
+            , roundRectClipState(snapshot.roundRectClipState)
+            , projectionPathMask(snapshot.projectionPathMask)
+            , op(shadowOpPtr) {}
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
new file mode 100644
index 0000000..39b7ecb
--- /dev/null
+++ b/libs/hwui/DeviceInfo.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <DeviceInfo.h>
+
+#include "Extensions.h"
+
+#include <GLES2/gl2.h>
+
+#include <thread>
+#include <mutex>
+
+namespace android {
+namespace uirenderer {
+
+static DeviceInfo* sDeviceInfo = nullptr;
+static std::once_flag sInitializedFlag;
+
+const DeviceInfo* DeviceInfo::get() {
+    return sDeviceInfo;
+}
+
+void DeviceInfo::initialize() {
+    std::call_once(sInitializedFlag, []() {
+        sDeviceInfo = new DeviceInfo();
+        sDeviceInfo->load();
+    });
+}
+
+void DeviceInfo::load() {
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
new file mode 100644
index 0000000..f576a4f
--- /dev/null
+++ b/libs/hwui/DeviceInfo.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef DEVICEINFO_H
+#define DEVICEINFO_H
+
+#include "Extensions.h"
+#include "utils/Macros.h"
+
+namespace android {
+namespace uirenderer {
+
+class DeviceInfo {
+    PREVENT_COPY_AND_ASSIGN(DeviceInfo);
+public:
+    // returns nullptr if DeviceInfo is not initialized yet
+    // Note this does not have a memory fence so it's up to the caller
+    // to use one if required. Normally this should not be necessary
+    static const DeviceInfo* get();
+
+    // only call this after GL has been initialized, or at any point if compiled
+    // with HWUI_NULL_GPU
+    static void initialize();
+
+    const Extensions& extensions() const { return mExtensions; }
+
+    int maxTextureSize() const { return mMaxTextureSize; }
+
+private:
+    DeviceInfo() {}
+    ~DeviceInfo() {}
+
+    void load();
+
+    Extensions mExtensions;
+    int mMaxTextureSize;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* DEVICEINFO_H */
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index fc08504..609103b 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -17,6 +17,14 @@
 #ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
 #define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
 
+#include "Canvas.h"
+#include "CanvasState.h"
+#include "DisplayList.h"
+#include "RenderNode.h"
+#include "ResourceCache.h"
+#include "SkiaCanvasProxy.h"
+#include "utils/Macros.h"
+
 #include <SkDrawFilter.h>
 #include <SkMatrix.h>
 #include <SkPaint.h>
@@ -25,13 +33,6 @@
 #include <SkTLazy.h>
 #include <cutils/compiler.h>
 
-#include "Canvas.h"
-#include "CanvasState.h"
-#include "DisplayList.h"
-#include "SkiaCanvasProxy.h"
-#include "RenderNode.h"
-#include "ResourceCache.h"
-
 namespace android {
 namespace uirenderer {
 
@@ -66,7 +67,7 @@
     virtual ~DisplayListCanvas();
 
     void reset(int width, int height);
-    __attribute__((warn_unused_result)) DisplayList* finishRecording();
+    WARN_UNUSED_RESULT DisplayList* finishRecording();
 
 // ----------------------------------------------------------------------------
 // HWUI Canvas state operations
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index cb638a4..772aa72 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1398,6 +1398,7 @@
     friend class RenderNode; // grant RenderNode access to info of child
     friend class DisplayList; // grant DisplayList access to info of child
     friend class DisplayListCanvas;
+    friend class TestUtils;
 public:
     DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent, bool clipIsSimple)
             : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr)
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index 6dd29ad..02caaa4 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -36,7 +36,7 @@
 
 
 Extensions::Extensions() {
-    StringCollection extensions((const char*) glGetString(GL_EXTENSIONS));
+    auto extensions = StringUtils::split((const char*) glGetString(GL_EXTENSIONS));
     mHasNPot = extensions.has("GL_OES_texture_npot");
     mHasFramebufferFetch = extensions.has("GL_NV_shader_framebuffer_fetch");
     mHasDiscardFramebuffer = extensions.has("GL_EXT_discard_framebuffer");
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 6689b88..67cc747 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -19,6 +19,9 @@
 
 #include <cutils/compiler.h>
 
+#include <string>
+#include <unordered_set>
+
 namespace android {
 namespace uirenderer {
 
@@ -26,7 +29,7 @@
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
-class ANDROID_API Extensions {
+class Extensions {
 public:
     Extensions();
 
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index 39cadd1..b117754 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -14,13 +14,14 @@
  * limitations under the License.
  */
 
-#include <GLES2/gl2.h>
+#include "LayerCache.h"
+
+#include "Caches.h"
+#include "Properties.h"
 
 #include <utils/Log.h>
 
-#include "Caches.h"
-#include "LayerCache.h"
-#include "Properties.h"
+#include <GLES2/gl2.h>
 
 namespace android {
 namespace uirenderer {
@@ -29,15 +30,9 @@
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
 
-LayerCache::LayerCache(): mSize(0), mMaxSize(MB(DEFAULT_LAYER_CACHE_SIZE)) {
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, nullptr) > 0) {
-        INIT_LOGD("  Setting layer cache size to %sMB", property);
-        setMaxSize(MB(atof(property)));
-    } else {
-        INIT_LOGD("  Using default layer cache size of %.2fMB", DEFAULT_LAYER_CACHE_SIZE);
-    }
-}
+LayerCache::LayerCache()
+        : mSize(0)
+        , mMaxSize(Properties::layerPoolSize) {}
 
 LayerCache::~LayerCache() {
     clear();
diff --git a/libs/hwui/OpReorderer.cpp b/libs/hwui/OpReorderer.cpp
index 163f7cc..b04f16f 100644
--- a/libs/hwui/OpReorderer.cpp
+++ b/libs/hwui/OpReorderer.cpp
@@ -16,12 +16,16 @@
 
 #include "OpReorderer.h"
 
-#include "utils/PaintUtils.h"
-#include "RenderNode.h"
 #include "LayerUpdateQueue.h"
+#include "RenderNode.h"
+#include "renderstate/OffscreenBufferPool.h"
+#include "utils/FatVector.h"
+#include "utils/PaintUtils.h"
 
-#include "SkCanvas.h"
-#include "utils/Trace.h"
+#include <SkCanvas.h>
+#include <SkPathOps.h>
+#include <utils/Trace.h>
+#include <utils/TypeHelpers.h>
 
 namespace android {
 namespace uirenderer {
@@ -30,8 +34,8 @@
 
 public:
     BatchBase(batchid_t batchId, BakedOpState* op, bool merging)
-        : mBatchId(batchId)
-        , mMerging(merging) {
+            : mBatchId(batchId)
+            , mMerging(merging) {
         mBounds = op->computedState.clippedBounds;
         mOps.push_back(op);
     }
@@ -204,9 +208,10 @@
 };
 
 OpReorderer::LayerReorderer::LayerReorderer(uint32_t width, uint32_t height,
-        const BeginLayerOp* beginLayerOp, RenderNode* renderNode)
+        const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode)
         : width(width)
         , height(height)
+        , repaintRect(repaintRect)
         , offscreenBuffer(renderNode ? renderNode->getLayer() : nullptr)
         , beginLayerOp(beginLayerOp)
         , renderNode(renderNode) {}
@@ -306,15 +311,19 @@
 
 OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
         uint32_t viewportWidth, uint32_t viewportHeight,
-        const std::vector< sp<RenderNode> >& nodes)
+        const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter)
         : mCanvasState(*this) {
     ATRACE_NAME("prepare drawing commands");
-    mLayerReorderers.emplace_back(viewportWidth, viewportHeight);
-        mLayerStack.push_back(0);
 
+    mLayerReorderers.reserve(layers.entries().size());
+    mLayerStack.reserve(layers.entries().size());
+
+    // Prepare to defer Fbo0
+    mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(clip));
+    mLayerStack.push_back(0);
     mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
             clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
-            Vector3());
+            lightCenter);
 
     // Render all layers to be updated, in order. Defer in reverse order, so that they'll be
     // updated in the order they're passed in (mLayerReorderers are issued to Renderer in reverse)
@@ -322,7 +331,8 @@
         RenderNode* layerNode = layers.entries()[i].renderNode;
         const Rect& layerDamage = layers.entries()[i].damage;
 
-        saveForLayer(layerNode->getWidth(), layerNode->getHeight(), nullptr, layerNode);
+        saveForLayer(layerNode->getWidth(), layerNode->getHeight(),
+                layerDamage, nullptr, layerNode);
         mCanvasState.writableSnapshot()->setClip(
                 layerDamage.left, layerDamage.top, layerDamage.right, layerDamage.bottom);
 
@@ -342,15 +352,17 @@
     }
 }
 
-OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList)
+OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList,
+        const Vector3& lightCenter)
         : mCanvasState(*this) {
     ATRACE_NAME("prepare drawing commands");
-
-    mLayerReorderers.emplace_back(viewportWidth, viewportHeight);
+    // Prepare to defer Fbo0
+    mLayerReorderers.emplace_back(viewportWidth, viewportHeight,
+            Rect(viewportWidth, viewportHeight));
     mLayerStack.push_back(0);
-
     mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
-            0, 0, viewportWidth, viewportHeight, Vector3());
+            0, 0, viewportWidth, viewportHeight, lightCenter);
+
     deferImpl(displayList);
 }
 
@@ -359,7 +371,7 @@
 void OpReorderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
 
 void OpReorderer::deferNodePropsAndOps(RenderNode& node) {
-    if (node.applyViewProperties(mCanvasState)) {
+    if (node.applyViewProperties(mCanvasState, mAllocator)) {
         // not rejected so render
         if (node.getLayer()) {
             // HW layer
@@ -375,6 +387,146 @@
     }
 }
 
+typedef key_value_pair_t<float, const RenderNodeOp*> ZRenderNodeOpPair;
+
+template <typename V>
+static void buildZSortedChildList(V* zTranslatedNodes,
+        const DisplayList& displayList, const DisplayList::Chunk& chunk) {
+    if (chunk.beginChildIndex == chunk.endChildIndex) return;
+
+    for (size_t i = chunk.beginChildIndex; i < chunk.endChildIndex; i++) {
+        RenderNodeOp* childOp = displayList.getChildren()[i];
+        RenderNode* child = childOp->renderNode;
+        float childZ = child->properties().getZ();
+
+        if (!MathUtils::isZero(childZ) && chunk.reorderChildren) {
+            zTranslatedNodes->push_back(ZRenderNodeOpPair(childZ, childOp));
+            childOp->skipInOrderDraw = true;
+        } else if (!child->properties().getProjectBackwards()) {
+            // regular, in order drawing DisplayList
+            childOp->skipInOrderDraw = false;
+        }
+    }
+
+    // Z sort any 3d children (stable-ness makes z compare fall back to standard drawing order)
+    std::stable_sort(zTranslatedNodes->begin(), zTranslatedNodes->end());
+}
+
+template <typename V>
+static size_t findNonNegativeIndex(const V& zTranslatedNodes) {
+    for (size_t i = 0; i < zTranslatedNodes.size(); i++) {
+        if (zTranslatedNodes[i].key >= 0.0f) return i;
+    }
+    return zTranslatedNodes.size();
+}
+
+template <typename V>
+void OpReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedNodes) {
+    const int size = zTranslatedNodes.size();
+    if (size == 0
+            || (mode == ChildrenSelectMode::Negative&& zTranslatedNodes[0].key > 0.0f)
+            || (mode == ChildrenSelectMode::Positive && zTranslatedNodes[size - 1].key < 0.0f)) {
+        // no 3d children to draw
+        return;
+    }
+
+    /**
+     * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
+     * with very similar Z heights to draw together.
+     *
+     * This way, if Views A & B have the same Z height and are both casting shadows, the shadows are
+     * underneath both, and neither's shadow is drawn on top of the other.
+     */
+    const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes);
+    size_t drawIndex, shadowIndex, endIndex;
+    if (mode == ChildrenSelectMode::Negative) {
+        drawIndex = 0;
+        endIndex = nonNegativeIndex;
+        shadowIndex = endIndex; // draw no shadows
+    } else {
+        drawIndex = nonNegativeIndex;
+        endIndex = size;
+        shadowIndex = drawIndex; // potentially draw shadow for each pos Z child
+    }
+
+    float lastCasterZ = 0.0f;
+    while (shadowIndex < endIndex || drawIndex < endIndex) {
+        if (shadowIndex < endIndex) {
+            const RenderNodeOp* casterNodeOp = zTranslatedNodes[shadowIndex].value;
+            const float casterZ = zTranslatedNodes[shadowIndex].key;
+            // attempt to render the shadow if the caster about to be drawn is its caster,
+            // OR if its caster's Z value is similar to the previous potential caster
+            if (shadowIndex == drawIndex || casterZ - lastCasterZ < 0.1f) {
+                deferShadow(*casterNodeOp);
+
+                lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
+                shadowIndex++;
+                continue;
+            }
+        }
+
+        const RenderNodeOp* childOp = zTranslatedNodes[drawIndex].value;
+        deferRenderNodeOp(*childOp);
+        drawIndex++;
+    }
+}
+
+void OpReorderer::deferShadow(const RenderNodeOp& casterNodeOp) {
+    auto& node = *casterNodeOp.renderNode;
+    auto& properties = node.properties();
+
+    if (properties.getAlpha() <= 0.0f
+            || properties.getOutline().getAlpha() <= 0.0f
+            || !properties.getOutline().getPath()
+            || properties.getScaleX() == 0
+            || properties.getScaleY() == 0) {
+        // no shadow to draw
+        return;
+    }
+
+    const SkPath* casterOutlinePath = properties.getOutline().getPath();
+    const SkPath* revealClipPath = properties.getRevealClip().getPath();
+    if (revealClipPath && revealClipPath->isEmpty()) return;
+
+    float casterAlpha = properties.getAlpha() * properties.getOutline().getAlpha();
+
+    // holds temporary SkPath to store the result of intersections
+    SkPath* frameAllocatedPath = nullptr;
+    const SkPath* casterPath = casterOutlinePath;
+
+    // intersect the shadow-casting path with the reveal, if present
+    if (revealClipPath) {
+        frameAllocatedPath = createFrameAllocatedPath();
+
+        Op(*casterPath, *revealClipPath, kIntersect_SkPathOp, frameAllocatedPath);
+        casterPath = frameAllocatedPath;
+    }
+
+    // intersect the shadow-casting path with the clipBounds, if present
+    if (properties.getClippingFlags() & CLIP_TO_CLIP_BOUNDS) {
+        if (!frameAllocatedPath) {
+            frameAllocatedPath = createFrameAllocatedPath();
+        }
+        Rect clipBounds;
+        properties.getClippingRectForFlags(CLIP_TO_CLIP_BOUNDS, &clipBounds);
+        SkPath clipBoundsPath;
+        clipBoundsPath.addRect(clipBounds.left, clipBounds.top,
+                clipBounds.right, clipBounds.bottom);
+
+        Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, frameAllocatedPath);
+        casterPath = frameAllocatedPath;
+    }
+
+    ShadowOp* shadowOp = new (mAllocator) ShadowOp(casterNodeOp, casterAlpha, casterPath,
+            mCanvasState.getLocalClipBounds(),
+            mCanvasState.currentSnapshot()->getRelativeLightCenter());
+    BakedOpState* bakedOpState = BakedOpState::tryShadowOpConstruct(
+            mAllocator, *mCanvasState.currentSnapshot(), shadowOp);
+    if (CC_LIKELY(bakedOpState)) {
+        currentLayer().deferUnmergeableOp(mAllocator, bakedOpState, OpBatchType::Shadow);
+    }
+}
+
 /**
  * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods.
  *
@@ -388,17 +540,20 @@
         MAP_OPS(OP_RECEIVER)
     };
     for (const DisplayList::Chunk& chunk : displayList.getChunks()) {
+        FatVector<ZRenderNodeOpPair, 16> zTranslatedNodes;
+        buildZSortedChildList(&zTranslatedNodes, displayList, chunk);
+
+        defer3dChildren(ChildrenSelectMode::Negative, zTranslatedNodes);
         for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
             const RecordedOp* op = displayList.getOps()[opIndex];
             receivers[op->opId](*this, *op);
         }
+        defer3dChildren(ChildrenSelectMode::Positive, zTranslatedNodes);
     }
 }
 
-void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) {
-    if (op.renderNode->nothingToDraw()) {
-        return;
-    }
+void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) {
+    if (op.renderNode->nothingToDraw()) return;
     int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
 
     // apply state from RecordedOp
@@ -412,6 +567,12 @@
     mCanvasState.restoreToCount(count);
 }
 
+void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) {
+    if (!op.skipInOrderDraw) {
+        deferRenderNodeOp(op);
+    }
+}
+
 static batchid_t tessellatedBatchId(const SkPaint& paint) {
     return paint.getPathEffect()
             ? OpBatchType::AlphaMaskTexture
@@ -439,17 +600,36 @@
     currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, OpBatchType::Vertices);
 }
 
-void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight,
+void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, const Rect& repaintRect,
         const BeginLayerOp* beginLayerOp, RenderNode* renderNode) {
 
+    auto previous = mCanvasState.currentSnapshot();
     mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
     mCanvasState.writableSnapshot()->transform->loadIdentity();
     mCanvasState.writableSnapshot()->initializeViewport(layerWidth, layerHeight);
     mCanvasState.writableSnapshot()->roundRectClipState = nullptr;
 
+    Vector3 lightCenter = previous->getRelativeLightCenter();
+    if (renderNode) {
+        Matrix4& inverse = renderNode->getLayer()->inverseTransformInWindow;
+        inverse.mapPoint3d(lightCenter);
+    } else {
+        // Combine all transforms used to present saveLayer content:
+        // parent content transform * canvas transform * bounds offset
+        Matrix4 contentTransform(*previous->transform);
+        contentTransform.multiply(beginLayerOp->localMatrix);
+        contentTransform.translate(beginLayerOp->unmappedBounds.left, beginLayerOp->unmappedBounds.top);
+
+        // inverse the total transform, to map light center into layer-relative space
+        Matrix4 inverse;
+        inverse.loadInverse(contentTransform);
+        inverse.mapPoint3d(lightCenter);
+    }
+    mCanvasState.writableSnapshot()->setRelativeLightCenter(lightCenter);
+
     // create a new layer, and push its index on the stack
     mLayerStack.push_back(mLayerReorderers.size());
-    mLayerReorderers.emplace_back(layerWidth, layerHeight, beginLayerOp, renderNode);
+    mLayerReorderers.emplace_back(layerWidth, layerHeight, repaintRect, beginLayerOp, renderNode);
 }
 
 void OpReorderer::restoreForLayer() {
@@ -462,7 +642,7 @@
 void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) {
     const uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth();
     const uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight();
-    saveForLayer(layerWidth, layerHeight, &op, nullptr);
+    saveForLayer(layerWidth, layerHeight, Rect(layerWidth, layerHeight), &op, nullptr);
 }
 
 void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) {
@@ -495,5 +675,9 @@
     LOG_ALWAYS_FATAL("unsupported");
 }
 
+void OpReorderer::onShadowOp(const ShadowOp& op) {
+    LOG_ALWAYS_FATAL("unsupported");
+}
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/OpReorderer.h b/libs/hwui/OpReorderer.h
index 77be402..09d5cbc 100644
--- a/libs/hwui/OpReorderer.h
+++ b/libs/hwui/OpReorderer.h
@@ -51,6 +51,7 @@
         AlphaMaskTexture,
         Text,
         ColorText,
+        Shadow,
 
         Count // must be last
     };
@@ -66,13 +67,13 @@
     class LayerReorderer {
     public:
         // Create LayerReorderer for Fbo0
-        LayerReorderer(uint32_t width, uint32_t height)
-                : LayerReorderer(width, height, nullptr, nullptr) {};
+        LayerReorderer(uint32_t width, uint32_t height, const Rect& repaintRect)
+                : LayerReorderer(width, height, repaintRect, nullptr, nullptr) {};
 
         // Create LayerReorderer for an offscreen layer, where beginLayerOp is present for a
         // saveLayer, renderNode is present for a HW layer.
         LayerReorderer(uint32_t width, uint32_t height,
-                const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
+                const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
 
         // iterate back toward target to see if anything drawn since should overlap the new op
         // if no target, merging ops still iterate to find similar batch to insert after
@@ -100,6 +101,7 @@
 
         const uint32_t width;
         const uint32_t height;
+        const Rect repaintRect;
         OffscreenBuffer* offscreenBuffer;
         const BeginLayerOp* beginLayerOp;
         const RenderNode* renderNode;
@@ -115,14 +117,15 @@
 
         // Maps batch ids to the most recent *non-merging* batch of that id
         OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr };
-
     };
+
 public:
     OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
             uint32_t viewportWidth, uint32_t viewportHeight,
-            const std::vector< sp<RenderNode> >& nodes);
+            const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter);
 
-    OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList);
+    OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList,
+            const Vector3& lightCenter);
 
     virtual ~OpReorderer() {}
 
@@ -152,18 +155,18 @@
             LayerReorderer& layer = mLayerReorderers[i];
             if (layer.renderNode) {
                 // cached HW layer - can't skip layer if empty
-                renderer.startLayer(layer.offscreenBuffer);
+                renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect);
                 layer.replayBakedOpsImpl((void*)&renderer, receivers);
                 renderer.endLayer();
             } else if (!layer.empty()) { // save layer - skip entire layer if empty
-                layer.offscreenBuffer = renderer.createLayer(layer.width, layer.height);
+                layer.offscreenBuffer = renderer.startTemporaryLayer(layer.width, layer.height);
                 layer.replayBakedOpsImpl((void*)&renderer, receivers);
                 renderer.endLayer();
             }
         }
 
         const LayerReorderer& fbo0 = mLayerReorderers[0];
-        renderer.startFrame(fbo0.width, fbo0.height);
+        renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect);
         fbo0.replayBakedOpsImpl((void*)&renderer, receivers);
         renderer.endFrame();
     }
@@ -182,8 +185,12 @@
     virtual GLuint getTargetFbo() const override { return 0; }
 
 private:
+    enum class ChildrenSelectMode {
+        Negative,
+        Positive
+    };
     void saveForLayer(uint32_t layerWidth, uint32_t layerHeight,
-            const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
+            const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
     void restoreForLayer();
 
     LayerReorderer& currentLayer() { return mLayerReorderers[mLayerStack.back()]; }
@@ -195,10 +202,21 @@
     // should always be surrounded by a save/restore pair
     void deferNodePropsAndOps(RenderNode& node);
 
+    void deferShadow(const RenderNodeOp& casterOp);
+
     void deferImpl(const DisplayList& displayList);
 
+    template <typename V>
+    void defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedNodes);
+
+    void deferRenderNodeOp(const RenderNodeOp& op);
+
     void replayBakedOpsImpl(void* arg, BakedOpDispatcher* receivers);
 
+    SkPath* createFrameAllocatedPath() {
+        mFrameAllocatedPaths.emplace_back(new SkPath);
+        return mFrameAllocatedPaths.back().get();
+    }
     /**
      * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type.
      *
@@ -209,6 +227,8 @@
     void on##Type(const Type& op);
     MAP_OPS(INTERNAL_OP_HANDLER)
 
+    std::vector<std::unique_ptr<SkPath> > mFrameAllocatedPaths;
+
     // List of every deferred layer's render state. Replayed in reverse order to render a frame.
     std::vector<LayerReorderer> mLayerReorderers;
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 8c3603b..12c4607 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2255,12 +2255,15 @@
 
     PathTexture* texture = mCaches.pathCache.get(path, paint);
     if (!texture) return;
-    const AutoTexture autoCleanup(texture);
 
     const float x = texture->left - texture->offset;
     const float y = texture->top - texture->offset;
 
     drawPathTexture(texture, x, y, paint);
+
+    if (texture->cleanup) {
+        mCaches.pathCache.remove(path, paint);
+    }
     mDirty = true;
 }
 
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index fd9ab18..06ea55a 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -396,6 +396,13 @@
     return texture;
 }
 
+void PathCache::remove(const SkPath* path, const SkPaint* paint)
+{
+    PathDescription entry(kShapePath, paint);
+    entry.shape.path.mGenerationID = path->getGenerationID();
+    mCache.remove(entry);
+}
+
 void PathCache::precache(const SkPath* path, const SkPaint* paint) {
     if (!Caches::getInstance().tasks.canRunTasks()) {
         return;
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 31f8d35..302e9f8 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -202,6 +202,7 @@
     PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
             bool useCenter, const SkPaint* paint);
     PathTexture* get(const SkPath* path, const SkPaint* paint);
+    void         remove(const SkPath* path, const SkPaint* paint);
 
     /**
      * Removes the specified path. This is meant to be called from threads
diff --git a/libs/hwui/PathParser.cpp b/libs/hwui/PathParser.cpp
new file mode 100644
index 0000000..35230ff
--- /dev/null
+++ b/libs/hwui/PathParser.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PathParser.h"
+
+#include "jni.h"
+
+#include <errno.h>
+#include <utils/Log.h>
+#include <sstream>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace uirenderer {
+
+static size_t nextStart(const char* s, size_t length, size_t startIndex) {
+    size_t index = startIndex;
+    while (index < length) {
+        char c = s[index];
+        // Note that 'e' or 'E' are not valid path commands, but could be
+        // used for floating point numbers' scientific notation.
+        // Therefore, when searching for next command, we should ignore 'e'
+        // and 'E'.
+        if ((((c - 'A') * (c - 'Z') <= 0) || ((c - 'a') * (c - 'z') <= 0))
+                && c != 'e' && c != 'E') {
+            return index;
+        }
+        index++;
+    }
+    return index;
+}
+
+/**
+ * Calculate the position of the next comma or space or negative sign
+ * @param s the string to search
+ * @param start the position to start searching
+ * @param result the result of the extraction, including the position of the
+ * the starting position of next number, whether it is ending with a '-'.
+ */
+static void extract(int* outEndPosition, bool* outEndWithNegOrDot, const char* s, int start, int end) {
+    // Now looking for ' ', ',', '.' or '-' from the start.
+    int currentIndex = start;
+    bool foundSeparator = false;
+    *outEndWithNegOrDot = false;
+    bool secondDot = false;
+    bool isExponential = false;
+    for (; currentIndex < end; currentIndex++) {
+        bool isPrevExponential = isExponential;
+        isExponential = false;
+        char currentChar = s[currentIndex];
+        switch (currentChar) {
+        case ' ':
+        case ',':
+            foundSeparator = true;
+            break;
+        case '-':
+            // The negative sign following a 'e' or 'E' is not a separator.
+            if (currentIndex != start && !isPrevExponential) {
+                foundSeparator = true;
+                *outEndWithNegOrDot = true;
+            }
+            break;
+        case '.':
+            if (!secondDot) {
+                secondDot = true;
+            } else {
+                // This is the second dot, and it is considered as a separator.
+                foundSeparator = true;
+                *outEndWithNegOrDot = true;
+            }
+            break;
+        case 'e':
+        case 'E':
+            isExponential = true;
+            break;
+        }
+        if (foundSeparator) {
+            break;
+        }
+    }
+    // In the case where nothing is found, we put the end position to the end of
+    // our extract range. Otherwise, end position will be where separator is found.
+    *outEndPosition = currentIndex;
+}
+
+static float parseFloat(PathParser::ParseResult* result, const char* startPtr, size_t expectedLength) {
+    char* endPtr = NULL;
+    float currentValue = strtof(startPtr, &endPtr);
+    if ((currentValue == HUGE_VALF || currentValue == -HUGE_VALF) && errno == ERANGE) {
+        result->failureOccurred = true;
+        result->failureMessage = "Float out of range:  ";
+        result->failureMessage.append(startPtr, expectedLength);
+    }
+    if (currentValue == 0 && endPtr == startPtr) {
+        // No conversion is done.
+        result->failureOccurred = true;
+        result->failureMessage = "Float format error when parsing: ";
+        result->failureMessage.append(startPtr, expectedLength);
+    }
+    return currentValue;
+}
+
+/**
+ * Parse the floats in the string.
+ *
+ * @param s the string containing a command and list of floats
+ * @return true on success
+ */
+static void getFloats(std::vector<float>* outPoints, PathParser::ParseResult* result,
+        const char* pathStr, int start, int end) {
+
+    if (pathStr[start] == 'z' || pathStr[start] == 'Z') {
+        return;
+    }
+    int startPosition = start + 1;
+    int endPosition = start;
+
+    // The startPosition should always be the first character of the
+    // current number, and endPosition is the character after the current
+    // number.
+    while (startPosition < end) {
+        bool endWithNegOrDot;
+        extract(&endPosition, &endWithNegOrDot, pathStr, startPosition, end);
+
+        if (startPosition < endPosition) {
+            float currentValue = parseFloat(result, &pathStr[startPosition],
+                    end - startPosition);
+            if (result->failureOccurred) {
+                return;
+            }
+            outPoints->push_back(currentValue);
+        }
+
+        if (endWithNegOrDot) {
+            // Keep the '-' or '.' sign with next number.
+            startPosition = endPosition;
+        } else {
+            startPosition = endPosition + 1;
+        }
+    }
+    return;
+}
+
+void PathParser::getPathDataFromString(PathData* data, ParseResult* result,
+        const char* pathStr, size_t strLen) {
+    if (pathStr == NULL) {
+        result->failureOccurred = true;
+        result->failureMessage = "Path string cannot be NULL.";
+        return;
+    }
+
+    size_t start = 0;
+    size_t end = 1;
+
+    while (end < strLen) {
+        end = nextStart(pathStr, strLen, end);
+        std::vector<float> points;
+        getFloats(&points, result, pathStr, start, end);
+        if (result->failureOccurred) {
+            return;
+        }
+        data->verbs.push_back(pathStr[start]);
+        data->verbSizes.push_back(points.size());
+        data->points.insert(data->points.end(), points.begin(), points.end());
+        start = end;
+        end++;
+    }
+
+    if ((end - start) == 1 && start < strLen) {
+        data->verbs.push_back(pathStr[start]);
+        data->verbSizes.push_back(0);
+    }
+    return;
+}
+
+void PathParser::dump(const PathData& data) {
+    // Print out the path data.
+    size_t start = 0;
+    for (size_t i = 0; i < data.verbs.size(); i++) {
+        std::ostringstream os;
+        os << data.verbs[i];
+        os << ", verb size: " << data.verbSizes[i];
+        for (size_t j = 0; j < data.verbSizes[i]; j++) {
+            os << " " << data.points[start + j];
+        }
+        start += data.verbSizes[i];
+        ALOGD("%s", os.str().c_str());
+    }
+
+    std::ostringstream os;
+    for (size_t i = 0; i < data.points.size(); i++) {
+        os << data.points[i] << ", ";
+    }
+    ALOGD("points are : %s", os.str().c_str());
+}
+
+void PathParser::parseStringForSkPath(SkPath* skPath, ParseResult* result, const char* pathStr, size_t strLen) {
+    PathData pathData;
+    getPathDataFromString(&pathData, result, pathStr, strLen);
+    if (result->failureOccurred) {
+        return;
+    }
+    // Check if there is valid data coming out of parsing the string.
+    if (pathData.verbs.size() == 0) {
+        result->failureOccurred = true;
+        result->failureMessage = "No verbs found in the string for pathData";
+        return;
+    }
+    VectorDrawablePath::verbsToPath(skPath, &pathData);
+    return;
+}
+
+}; // namespace uirenderer
+}; //namespace android
diff --git a/libs/hwui/PathParser.h b/libs/hwui/PathParser.h
new file mode 100644
index 0000000..a9c1e60
--- /dev/null
+++ b/libs/hwui/PathParser.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_PATHPARSER_H
+#define ANDROID_HWUI_PATHPARSER_H
+
+#include "VectorDrawablePath.h"
+
+#include <jni.h>
+#include <android/log.h>
+#include <cutils/compiler.h>
+
+#include <string>
+
+namespace android {
+namespace uirenderer {
+
+
+class PathParser {
+public:
+    struct ANDROID_API ParseResult {
+        bool failureOccurred = false;
+        std::string failureMessage;
+    };
+    /**
+     * Parse the string literal and create a Skia Path. Return true on success.
+     */
+    ANDROID_API static void parseStringForSkPath(SkPath* outPath, ParseResult* result,
+            const char* pathStr, size_t strLength);
+    static void getPathDataFromString(PathData* outData, ParseResult* result,
+            const char* pathStr, size_t strLength);
+    static void dump(const PathData& data);
+};
+
+}; // namespace uirenderer
+}; // namespace android
+#endif //ANDROID_HWUI_PATHPARSER_H
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index e818186..0669596 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -37,6 +37,7 @@
 bool Properties::enablePartialUpdates = true;
 
 float Properties::textGamma = DEFAULT_TEXT_GAMMA;
+int Properties::layerPoolSize = DEFAULT_LAYER_CACHE_SIZE;
 
 DebugLevel Properties::debugLevel = kDebugDisabled;
 OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
@@ -52,10 +53,19 @@
 ProfileType Properties::sProfileType = ProfileType::None;
 bool Properties::sDisableProfileBars = false;
 
+static int property_get_int(const char* key, int defaultValue) {
+    char buf[PROPERTY_VALUE_MAX] = {'\0',};
+
+    if (property_get(key, buf, "") > 0) {
+        return atoi(buf);
+    }
+    return defaultValue;
+}
+
 static float property_get_float(const char* key, float defaultValue) {
     char buf[PROPERTY_VALUE_MAX] = {'\0',};
 
-    if (property_get(PROPERTY_PROFILE, buf, "") > 0) {
+    if (property_get(key, buf, "") > 0) {
         return atof(buf);
     }
     return defaultValue;
@@ -114,16 +124,14 @@
 
     showDirtyRegions = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
 
-    debugLevel = kDebugDisabled;
-    if (property_get(PROPERTY_DEBUG, property, nullptr) > 0) {
-        debugLevel = (DebugLevel) atoi(property);
-    }
+    debugLevel = (DebugLevel) property_get_int(PROPERTY_DEBUG, kDebugDisabled);
 
     skipEmptyFrames = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE, true);
     useBufferAge = property_get_bool(PROPERTY_USE_BUFFER_AGE, true);
     enablePartialUpdates = property_get_bool(PROPERTY_ENABLE_PARTIAL_UPDATES, true);
 
     textGamma = property_get_float(PROPERTY_TEXT_GAMMA, DEFAULT_TEXT_GAMMA);
+    layerPoolSize = MB(property_get_float(PROPERTY_LAYER_CACHE_SIZE, DEFAULT_LAYER_CACHE_SIZE));
 
     return (prevDebugLayersUpdates != debugLayersUpdates)
             || (prevDebugOverdraw != debugOverdraw)
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 1293c78..1dde7e0 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -267,6 +267,8 @@
 
     static float textGamma;
 
+    static int layerPoolSize;
+
     static DebugLevel debugLevel;
     static OverdrawColorSet overdrawColorSet;
     static StencilClipDebug debugStencilClip;
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index 9ae868a..ef05367 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -17,10 +17,11 @@
 #ifndef ANDROID_HWUI_RECORDED_OP_H
 #define ANDROID_HWUI_RECORDED_OP_H
 
-#include "utils/LinearAllocator.h"
-#include "Rect.h"
 #include "Matrix.h"
+#include "Rect.h"
 #include "RenderNode.h"
+#include "utils/LinearAllocator.h"
+#include "Vector.h"
 
 #include "SkXfermode.h"
 
@@ -43,6 +44,7 @@
         OP_FN(BitmapOp) \
         OP_FN(RectOp) \
         OP_FN(RenderNodeOp) \
+        OP_FN(ShadowOp) \
         OP_FN(SimpleRectsOp) \
         OP_FN(BeginLayerOp) \
         OP_FN(EndLayerOp) \
@@ -93,6 +95,7 @@
             : SUPER_PAINTLESS(RenderNodeOp)
             , renderNode(renderNode) {}
     RenderNode * renderNode; // not const, since drawing modifies it (somehow...)
+    bool skipInOrderDraw = false;
 };
 
 struct BitmapOp : RecordedOp {
@@ -108,6 +111,34 @@
             : SUPER(RectOp) {}
 };
 
+/**
+ * Real-time, dynamic-lit shadow.
+ *
+ * Uses invalid/empty bounds and matrix since ShadowOp bounds aren't known at defer time,
+ * and are resolved dynamically, and transform isn't needed.
+ *
+ * State construction handles these properties specially, ignoring matrix/bounds.
+ */
+struct ShadowOp : RecordedOp {
+    ShadowOp(const RenderNodeOp& casterOp, float casterAlpha, const SkPath* casterPath,
+            const Rect& clipRect, const Vector3& lightCenter)
+            : RecordedOp(RecordedOpId::ShadowOp, Rect(), Matrix4::identity(), clipRect, nullptr)
+            , shadowMatrixXY(casterOp.localMatrix)
+            , shadowMatrixZ(casterOp.localMatrix)
+            , casterAlpha(casterAlpha)
+            , casterPath(casterPath)
+            , lightCenter(lightCenter) {
+        const RenderNode& node = *casterOp.renderNode;
+        node.applyViewPropertyTransforms(shadowMatrixXY, false);
+        node.applyViewPropertyTransforms(shadowMatrixZ, true);
+    };
+    Matrix4 shadowMatrixXY;
+    Matrix4 shadowMatrixZ;
+    const float casterAlpha;
+    const SkPath* casterPath;
+    const Vector3 lightCenter;
+};
+
 struct SimpleRectsOp : RecordedOp { // Filled, no AA (TODO: better name?)
     SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount)
             : SUPER(SimpleRectsOp)
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 7c460b1..6ab253c 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -40,7 +40,7 @@
 
     mState.initializeSaveStack(width, height, 0, 0, width, height, Vector3());
 
-    mDeferredBarrierType = kBarrier_InOrder;
+    mDeferredBarrierType = DeferredBarrierType::InOrder;
     mState.setDirtyClip(false);
     mRestoreSaveCount = -1;
 }
@@ -156,7 +156,7 @@
 
     snapshot.flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer;
     snapshot.initializeViewport(untransformedBounds.getWidth(), untransformedBounds.getHeight());
-    snapshot.resetTransform(-untransformedBounds.left, -untransformedBounds.top, 0.0f);
+    snapshot.transform->loadTranslate(-untransformedBounds.left, -untransformedBounds.top, 0.0f);
 
     Rect clip = layerBounds;
     clip.translate(-untransformedBounds.left, -untransformedBounds.top);
@@ -432,17 +432,17 @@
     // TODO: validate if "addDrawOp" quickrejection logic is useful before adding
     int insertIndex = mDisplayList->ops.size();
     mDisplayList->ops.push_back(op);
-    if (mDeferredBarrierType != kBarrier_None) {
+    if (mDeferredBarrierType != DeferredBarrierType::None) {
         // op is first in new chunk
         mDisplayList->chunks.emplace_back();
         DisplayList::Chunk& newChunk = mDisplayList->chunks.back();
         newChunk.beginOpIndex = insertIndex;
         newChunk.endOpIndex = insertIndex + 1;
-        newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder);
+        newChunk.reorderChildren = (mDeferredBarrierType == DeferredBarrierType::OutOfOrder);
 
         int nextChildIndex = mDisplayList->children.size();
         newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex;
-        mDeferredBarrierType = kBarrier_None;
+        mDeferredBarrierType = DeferredBarrierType::None;
     } else {
         // standard case - append to existing chunk
         mDisplayList->chunks.back().endOpIndex = insertIndex + 1;
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 8a56475..f26b0c8 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -20,11 +20,12 @@
 #include "Canvas.h"
 #include "CanvasState.h"
 #include "DisplayList.h"
-#include "utils/LinearAllocator.h"
-#include "utils/NinePatch.h"
 #include "ResourceCache.h"
 #include "SkiaCanvasProxy.h"
 #include "Snapshot.h"
+#include "utils/LinearAllocator.h"
+#include "utils/Macros.h"
+#include "utils/NinePatch.h"
 
 #include <SkDrawFilter.h>
 #include <SkPaint.h>
@@ -39,17 +40,25 @@
 struct RecordedOp;
 
 class RecordingCanvas: public Canvas, public CanvasStateClient {
+    enum class DeferredBarrierType {
+        None,
+        InOrder,
+        OutOfOrder,
+    };
 public:
     RecordingCanvas(size_t width, size_t height);
     virtual ~RecordingCanvas();
 
     void reset(int width, int height);
-    __attribute__((warn_unused_result)) DisplayList* finishRecording();
+    WARN_UNUSED_RESULT DisplayList* finishRecording();
 
 // ----------------------------------------------------------------------------
 // MISC HWUI OPERATIONS - TODO: CATEGORIZE
 // ----------------------------------------------------------------------------
-    void insertReorderBarrier(bool enableReorder) {}
+    void insertReorderBarrier(bool enableReorder) {
+        mDeferredBarrierType = enableReorder
+                ? DeferredBarrierType::OutOfOrder : DeferredBarrierType::InOrder;
+    }
     void drawRenderNode(RenderNode* renderNode);
 
 // ----------------------------------------------------------------------------
@@ -176,11 +185,6 @@
     virtual bool drawTextAbsolutePos() const override { return false; }
 
 private:
-    enum DeferredBarrierType {
-        kBarrier_None,
-        kBarrier_InOrder,
-        kBarrier_OutOfOrder,
-    };
 
     void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
     void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint);
@@ -290,7 +294,7 @@
     CanvasState mState;
     std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy;
     ResourceCache& mResourceCache;
-    DeferredBarrierType mDeferredBarrierType = kBarrier_None;
+    DeferredBarrierType mDeferredBarrierType = DeferredBarrierType::None;
     DisplayList* mDisplayList = nullptr;
     bool mHighContrastText = false;
     SkAutoTUnref<SkDrawFilter> mDrawFilter;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 0601944..2713f46 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -248,22 +248,31 @@
     }
 }
 
-layer_t* createLayer(RenderState& renderState, uint32_t width, uint32_t height) {
+static layer_t* createLayer(RenderState& renderState, uint32_t width, uint32_t height) {
 #if HWUI_NEW_OPS
-    return BakedOpRenderer::createOffscreenBuffer(renderState, width, height);
+    return renderState.layerPool().get(renderState, width, height);
 #else
     return LayerRenderer::createRenderLayer(renderState, width, height);
 #endif
 }
 
-void destroyLayer(layer_t* layer) {
+static void destroyLayer(layer_t* layer) {
 #if HWUI_NEW_OPS
-    BakedOpRenderer::destroyOffscreenBuffer(layer);
+    RenderState& renderState = layer->renderState;
+    renderState.layerPool().putOrDelete(layer);
 #else
     LayerRenderer::destroyLayer(layer);
 #endif
 }
 
+static bool layerMatchesWidthAndHeight(layer_t* layer, int width, int height) {
+#if HWUI_NEW_OPS
+    return layer->viewportWidth == (uint32_t) width && layer->viewportHeight == (uint32_t)height;
+#else
+    return layer->layer.getWidth() == width && layer->layer.getHeight() == height;
+#endif
+}
+
 void RenderNode::pushLayerUpdate(TreeInfo& info) {
     LayerType layerType = properties().effectiveLayerType();
     // If we are not a layer OR we cannot be rendered (eg, view was detached)
@@ -278,15 +287,16 @@
 
     bool transformUpdateNeeded = false;
     if (!mLayer) {
-            mLayer = createLayer(info.canvasContext.getRenderState(), getWidth(), getHeight());
-            damageSelf(info);
-            transformUpdateNeeded = true;
+        mLayer = createLayer(info.canvasContext.getRenderState(), getWidth(), getHeight());
+        damageSelf(info);
+        transformUpdateNeeded = true;
+    } else if (!layerMatchesWidthAndHeight(mLayer, getWidth(), getHeight())) {
 #if HWUI_NEW_OPS
-    } else if (mLayer->viewportWidth != getWidth() || mLayer->viewportHeight != getHeight()) {
-        // TODO: allow it to grow larger
-        if (getWidth() > mLayer->texture.width || getHeight() > mLayer->texture.height) {
+        RenderState& renderState = mLayer->renderState;
+        if (properties().fitsOnLayer()) {
+            mLayer = renderState.layerPool().resize(mLayer, getWidth(), getHeight());
+        } else {
 #else
-    } else if (mLayer->layer.getWidth() != getWidth() || mLayer->layer.getHeight() != getHeight()) {
         if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) {
 #endif
             destroyLayer(mLayer);
@@ -304,7 +314,7 @@
         if (info.errorHandler) {
             std::ostringstream err;
             err << "Unable to create layer for " << getName();
-            const uint32_t  maxTextureSize = Caches::getInstance().maxTextureSize;
+            const int maxTextureSize = Caches::getInstance().maxTextureSize;
             if (getWidth() > maxTextureSize || getHeight() > maxTextureSize) {
                 err << ", size " << getWidth() << "x" << getHeight()
                         << " exceeds max size " << maxTextureSize;
@@ -316,15 +326,11 @@
         return;
     }
 
-    if (transformUpdateNeeded) {
+    if (transformUpdateNeeded && mLayer) {
         // update the transform in window of the layer to reset its origin wrt light source position
         Matrix4 windowTransform;
         info.damageAccumulator->computeCurrentTransform(&windowTransform);
-#if HWUI_NEW_OPS
-        // TODO: update layer transform (perhaps as part of enqueueLayerWithDamage)
-#else
         mLayer->setWindowTransform(windowTransform);
-#endif
     }
 
 #if HWUI_NEW_OPS
@@ -518,7 +524,7 @@
     }
 }
 
-bool RenderNode::applyViewProperties(CanvasState& canvasState) const {
+bool RenderNode::applyViewProperties(CanvasState& canvasState, LinearAllocator& allocator) const {
     const Outline& outline = properties().getOutline();
     if (properties().getAlpha() <= 0
             || (outline.getShouldClip() && outline.isEmpty())
@@ -542,6 +548,48 @@
             canvasState.concatMatrix(*properties().getTransformMatrix());
         }
     }
+
+    const bool isLayer = properties().effectiveLayerType() != LayerType::None;
+    int clipFlags = properties().getClippingFlags();
+    if (properties().getAlpha() < 1) {
+        if (isLayer) {
+            clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer
+        }
+        if (CC_LIKELY(isLayer || !properties().getHasOverlappingRendering())) {
+            // simply scale rendering content's alpha
+            canvasState.scaleAlpha(properties().getAlpha());
+        } else {
+            // savelayer needed to create an offscreen buffer
+            Rect layerBounds(0, 0, getWidth(), getHeight());
+            if (clipFlags) {
+                properties().getClippingRectForFlags(clipFlags, &layerBounds);
+                clipFlags = 0; // all clipping done by savelayer
+            }
+            LOG_ALWAYS_FATAL("TODO: savelayer");
+        }
+
+        if (CC_UNLIKELY(ATRACE_ENABLED() && properties().promotedToLayer())) {
+            // pretend alpha always causes savelayer to warn about
+            // performance problem affecting old versions
+            ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", getName(), getWidth(), getHeight());
+        }
+    }
+    if (clipFlags) {
+        Rect clipRect;
+        properties().getClippingRectForFlags(clipFlags, &clipRect);
+        canvasState.clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
+                SkRegion::kIntersect_Op);
+    }
+
+    // TODO: support nesting round rect clips
+    if (mProperties.getRevealClip().willClip()) {
+        Rect bounds;
+        mProperties.getRevealClip().getBounds(&bounds);
+        canvasState.setClippingRoundRect(allocator,
+                bounds, mProperties.getRevealClip().getRadius());
+    } else if (mProperties.getOutline().willClip()) {
+        canvasState.setClippingOutline(allocator, &(mProperties.getOutline()));
+    }
     return !canvasState.quickRejectConservative(
             0, 0, properties().getWidth(), properties().getHeight());
 }
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 3500cb2..bae5ebe 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -171,11 +171,11 @@
         return mStagingProperties;
     }
 
-    uint32_t getWidth() {
+    int getWidth() const {
         return properties().getWidth();
     }
 
-    uint32_t getHeight() {
+    int getHeight() const {
         return properties().getHeight();
     }
 
@@ -188,7 +188,7 @@
     AnimatorManager& animators() { return mAnimatorManager; }
 
     // Returns false if the properties dictate the subtree contained in this RenderNode won't render
-    bool applyViewProperties(CanvasState& canvasState) const;
+    bool applyViewProperties(CanvasState& canvasState, LinearAllocator& allocator) const;
 
     void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const;
 
@@ -201,7 +201,6 @@
                 || properties().getScaleY() == 0;
     }
 
-    // Only call if RenderNode has DisplayList...
     const DisplayList* getDisplayList() const {
         return mDisplayList;
     }
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index abef806..0bd5b65 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -16,23 +16,24 @@
 #ifndef RENDERNODEPROPERTIES_H
 #define RENDERNODEPROPERTIES_H
 
-#include <algorithm>
-#include <stddef.h>
-#include <vector>
-#include <cutils/compiler.h>
-#include <androidfw/ResourceTypes.h>
-#include <utils/Log.h>
+#include "Caches.h"
+#include "DeviceInfo.h"
+#include "Rect.h"
+#include "RevealClip.h"
+#include "Outline.h"
+#include "utils/MathUtils.h"
 
 #include <SkCamera.h>
 #include <SkMatrix.h>
 #include <SkRegion.h>
 #include <SkXfermode.h>
 
-#include "Caches.h"
-#include "Rect.h"
-#include "RevealClip.h"
-#include "Outline.h"
-#include "utils/MathUtils.h"
+#include <algorithm>
+#include <stddef.h>
+#include <vector>
+#include <cutils/compiler.h>
+#include <androidfw/ResourceTypes.h>
+#include <utils/Log.h>
 
 class SkBitmap;
 class SkColorFilter;
@@ -607,11 +608,16 @@
                 && getOutline().getAlpha() != 0.0f;
     }
 
+    bool fitsOnLayer() const {
+        const DeviceInfo* deviceInfo = DeviceInfo::get();
+        LOG_ALWAYS_FATAL_IF(!deviceInfo, "DeviceInfo uninitialized");
+        return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize()
+                        && mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
+    }
+
     bool promotedToLayer() const {
-        const int maxTextureSize = Caches::getInstance().maxTextureSize;
         return mLayerProperties.mType == LayerType::None
-                && mPrimitiveFields.mWidth <= maxTextureSize
-                && mPrimitiveFields.mHeight <= maxTextureSize
+                && fitsOnLayer()
                 && (mComputedFields.mNeedLayerForFunctors
                         || (!MathUtils::isZero(mPrimitiveFields.mAlpha)
                                 && mPrimitiveFields.mAlpha < 1
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index eb0fa74..e94a70a 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -76,6 +76,11 @@
     ALOGD("light center %f %f %f %d",
             adjustedLightCenter.x, adjustedLightCenter.y, adjustedLightCenter.z, lightRadius);
 #endif
+    if (isnan(adjustedLightCenter.x)
+            || isnan(adjustedLightCenter.y)
+            || isnan(adjustedLightCenter.z)) {
+        return;
+    }
 
     // light position (because it's in local space) needs to compensate for receiver transform
     // TODO: should apply to light orientation, not just position
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index a8f8134..6d3dfac 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -240,11 +240,15 @@
     return count;
 }
 
+// The SkiaCanvas::restore operation layers on the capability to preserve
+// either (or both) the matrix and/or clip state after a SkCanvas::restore
+// operation. It does this by explicitly saving off the clip & matrix state
+// when requested and playing it back after the SkCanvas::restore.
 void SkiaCanvas::restore() {
     const SaveRec* rec = (NULL == mSaveStack.get())
             ? NULL
             : static_cast<SaveRec*>(mSaveStack->back());
-    int currentSaveCount = mCanvas->getSaveCount() - 1;
+    int currentSaveCount = mCanvas->getSaveCount();
     SkASSERT(NULL == rec || currentSaveCount >= rec->saveCount);
 
     if (NULL == rec || rec->saveCount != currentSaveCount) {
@@ -262,8 +266,9 @@
     }
 
     SkTArray<SkClipStack::Element> savedClips;
+    int topClipStackFrame = mCanvas->getClipStack()->getSaveCount();
     if (preserveClip) {
-        saveClipsForFrame(savedClips, currentSaveCount);
+        saveClipsForFrame(savedClips, topClipStackFrame);
     }
 
     mCanvas->restore();
@@ -272,7 +277,11 @@
         mCanvas->setMatrix(savedMatrix);
     }
 
-    if (preserveClip && !savedClips.empty()) {
+    if (preserveClip && !savedClips.empty() &&
+        topClipStackFrame != mCanvas->getClipStack()->getSaveCount()) {
+        // Only reapply the saved clips if the top clip stack frame was actually
+        // popped by restore().  If it wasn't, it means it doesn't belong to the
+        // restored canvas frame (SkCanvas lazy save/restore kicked in).
         applyClips(savedClips);
     }
 
@@ -322,21 +331,23 @@
     }
 
     SaveRec* rec = static_cast<SaveRec*>(mSaveStack->push_back());
-    // Store the save counter in the SkClipStack domain.
-    // (0-based, equal to the number of save ops on the stack).
-    rec->saveCount = mCanvas->getSaveCount() - 1;
+    rec->saveCount = mCanvas->getSaveCount();
     rec->saveFlags = flags;
 }
 
-void SkiaCanvas::saveClipsForFrame(SkTArray<SkClipStack::Element>& clips, int frameSaveCount) {
+void SkiaCanvas::saveClipsForFrame(SkTArray<SkClipStack::Element>& clips,
+                                   int saveCountToBackup) {
+    // Each SkClipStack::Element stores the index of the canvas save
+    // with which it is associated. Backup only those Elements that
+    // are associated with 'saveCountToBackup'
     SkClipStack::Iter clipIterator(*mCanvas->getClipStack(),
                                    SkClipStack::Iter::kTop_IterStart);
-    while (const SkClipStack::Element* elem = clipIterator.next()) {
-        if (elem->getSaveCount() < frameSaveCount) {
-            // done with the current frame.
+    while (const SkClipStack::Element* elem = clipIterator.prev()) {
+        if (elem->getSaveCount() < saveCountToBackup) {
+            // done with the target save count.
             break;
         }
-        SkASSERT(elem->getSaveCount() == frameSaveCount);
+        SkASSERT(elem->getSaveCount() == saveCountToBackup);
         clips.push_back(*elem);
     }
 }
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 0a58f4b..2f535bb 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -130,6 +130,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void Snapshot::resetTransform(float x, float y, float z) {
+#if HWUI_NEW_OPS
+    LOG_ALWAYS_FATAL("not supported - light center managed differently");
+#else
     // before resetting, map current light pos with inverse of current transform
     Vector3 center = mRelativeLightCenter;
     mat4 inverse;
@@ -139,6 +142,7 @@
 
     transform = &mTransformRoot;
     transform->loadTranslate(x, y, z);
+#endif
 }
 
 void Snapshot::buildScreenSpaceTransform(Matrix4* outTransform) const {
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index bdce73c..759e39b 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -741,7 +741,7 @@
             // vertex's location.
             int newPenumbraNumber = indexDelta - 1;
 
-            float accumulatedDeltaLength[newPenumbraNumber];
+            float accumulatedDeltaLength[indexDelta];
             float totalDeltaLength = 0;
 
             // To save time, cache the previous umbra vertex info outside the loop
diff --git a/libs/hwui/VectorDrawablePath.cpp b/libs/hwui/VectorDrawablePath.cpp
new file mode 100644
index 0000000..05ea2da
--- /dev/null
+++ b/libs/hwui/VectorDrawablePath.cpp
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VectorDrawablePath.h"
+
+#include "PathParser.h"
+
+#include <math.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace uirenderer {
+
+class PathResolver {
+public:
+    float currentX = 0;
+    float currentY = 0;
+    float ctrlPointX = 0;
+    float ctrlPointY = 0;
+    float currentSegmentStartX = 0;
+    float currentSegmentStartY = 0;
+    void addCommand(SkPath* outPath, char previousCmd,
+            char cmd, const std::vector<float>* points, size_t start, size_t end);
+};
+
+VectorDrawablePath::VectorDrawablePath(const char* pathStr, size_t strLength) {
+    PathParser::ParseResult result;
+    PathParser::getPathDataFromString(&mData, &result, pathStr, strLength);
+    if (!result.failureOccurred) {
+        verbsToPath(&mSkPath, &mData);
+    }
+}
+
+VectorDrawablePath::VectorDrawablePath(const PathData& data) {
+    mData = data;
+    // Now we need to construct a path
+    verbsToPath(&mSkPath, &data);
+}
+
+VectorDrawablePath::VectorDrawablePath(const VectorDrawablePath& path) {
+    mData = path.mData;
+    verbsToPath(&mSkPath, &mData);
+}
+
+bool VectorDrawablePath::canMorph(const PathData& morphTo) {
+    if (mData.verbs.size() != morphTo.verbs.size()) {
+        return false;
+    }
+
+    for (unsigned int i = 0; i < mData.verbs.size(); i++) {
+        if (mData.verbs[i] != morphTo.verbs[i]
+                || mData.verbSizes[i] != morphTo.verbSizes[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool VectorDrawablePath::canMorph(const VectorDrawablePath& path) {
+    return canMorph(path.mData);
+}
+ /**
+ * Convert an array of PathVerb to Path.
+ */
+void VectorDrawablePath::verbsToPath(SkPath* outPath, const PathData* data) {
+    PathResolver resolver;
+    char previousCommand = 'm';
+    size_t start = 0;
+    outPath->reset();
+    for (unsigned int i = 0; i < data->verbs.size(); i++) {
+        size_t verbSize = data->verbSizes[i];
+        resolver.addCommand(outPath, previousCommand, data->verbs[i], &data->points, start,
+                start + verbSize);
+        previousCommand = data->verbs[i];
+        start += verbSize;
+    }
+}
+
+/**
+ * The current PathVerb will be interpolated between the
+ * <code>nodeFrom</code> and <code>nodeTo</code> according to the
+ * <code>fraction</code>.
+ *
+ * @param nodeFrom The start value as a PathVerb.
+ * @param nodeTo The end value as a PathVerb
+ * @param fraction The fraction to interpolate.
+ */
+void VectorDrawablePath::interpolatePaths(PathData* outData,
+        const PathData* from, const PathData* to, float fraction) {
+    outData->points.resize(from->points.size());
+    outData->verbSizes = from->verbSizes;
+    outData->verbs = from->verbs;
+
+    for (size_t i = 0; i < from->points.size(); i++) {
+        outData->points[i] = from->points[i] * (1 - fraction) + to->points[i] * fraction;
+    }
+}
+
+/**
+ * Converts an arc to cubic Bezier segments and records them in p.
+ *
+ * @param p The target for the cubic Bezier segments
+ * @param cx The x coordinate center of the ellipse
+ * @param cy The y coordinate center of the ellipse
+ * @param a The radius of the ellipse in the horizontal direction
+ * @param b The radius of the ellipse in the vertical direction
+ * @param e1x E(eta1) x coordinate of the starting point of the arc
+ * @param e1y E(eta2) y coordinate of the starting point of the arc
+ * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
+ * @param start The start angle of the arc on the ellipse
+ * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
+ */
+static void arcToBezier(SkPath* p,
+        double cx,
+        double cy,
+        double a,
+        double b,
+        double e1x,
+        double e1y,
+        double theta,
+        double start,
+        double sweep) {
+    // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
+    // and http://www.spaceroots.org/documents/ellipse/node22.html
+
+    // Maximum of 45 degrees per cubic Bezier segment
+    int numSegments = ceil(fabs(sweep * 4 / M_PI));
+
+    double eta1 = start;
+    double cosTheta = cos(theta);
+    double sinTheta = sin(theta);
+    double cosEta1 = cos(eta1);
+    double sinEta1 = sin(eta1);
+    double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+    double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
+
+    double anglePerSegment = sweep / numSegments;
+    for (int i = 0; i < numSegments; i++) {
+        double eta2 = eta1 + anglePerSegment;
+        double sinEta2 = sin(eta2);
+        double cosEta2 = cos(eta2);
+        double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
+        double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
+        double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
+        double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
+        double tanDiff2 = tan((eta2 - eta1) / 2);
+        double alpha =
+                sin(eta2 - eta1) * (sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
+        double q1x = e1x + alpha * ep1x;
+        double q1y = e1y + alpha * ep1y;
+        double q2x = e2x - alpha * ep2x;
+        double q2y = e2y - alpha * ep2y;
+
+        p->cubicTo((float) q1x,
+                (float) q1y,
+                (float) q2x,
+                (float) q2y,
+                (float) e2x,
+                (float) e2y);
+        eta1 = eta2;
+        e1x = e2x;
+        e1y = e2y;
+        ep1x = ep2x;
+        ep1y = ep2y;
+    }
+}
+
+inline double toRadians(float theta) { return theta * M_PI / 180;}
+
+static void drawArc(SkPath* p,
+        float x0,
+        float y0,
+        float x1,
+        float y1,
+        float a,
+        float b,
+        float theta,
+        bool isMoreThanHalf,
+        bool isPositiveArc) {
+
+    /* Convert rotation angle from degrees to radians */
+    double thetaD = toRadians(theta);
+    /* Pre-compute rotation matrix entries */
+    double cosTheta = cos(thetaD);
+    double sinTheta = sin(thetaD);
+    /* Transform (x0, y0) and (x1, y1) into unit space */
+    /* using (inverse) rotation, followed by (inverse) scale */
+    double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
+    double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
+    double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
+    double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
+
+    /* Compute differences and averages */
+    double dx = x0p - x1p;
+    double dy = y0p - y1p;
+    double xm = (x0p + x1p) / 2;
+    double ym = (y0p + y1p) / 2;
+    /* Solve for intersecting unit circles */
+    double dsq = dx * dx + dy * dy;
+    if (dsq == 0.0) {
+        ALOGW("Points are coincident");
+        return; /* Points are coincident */
+    }
+    double disc = 1.0 / dsq - 1.0 / 4.0;
+    if (disc < 0.0) {
+        ALOGW("Points are too far apart %f", dsq);
+        float adjust = (float) (sqrt(dsq) / 1.99999);
+        drawArc(p, x0, y0, x1, y1, a * adjust,
+                b * adjust, theta, isMoreThanHalf, isPositiveArc);
+        return; /* Points are too far apart */
+    }
+    double s = sqrt(disc);
+    double sdx = s * dx;
+    double sdy = s * dy;
+    double cx;
+    double cy;
+    if (isMoreThanHalf == isPositiveArc) {
+        cx = xm - sdy;
+        cy = ym + sdx;
+    } else {
+        cx = xm + sdy;
+        cy = ym - sdx;
+    }
+
+    double eta0 = atan2((y0p - cy), (x0p - cx));
+
+    double eta1 = atan2((y1p - cy), (x1p - cx));
+
+    double sweep = (eta1 - eta0);
+    if (isPositiveArc != (sweep >= 0)) {
+        if (sweep > 0) {
+            sweep -= 2 * M_PI;
+        } else {
+            sweep += 2 * M_PI;
+        }
+    }
+
+    cx *= a;
+    cy *= b;
+    double tcx = cx;
+    cx = cx * cosTheta - cy * sinTheta;
+    cy = tcx * sinTheta + cy * cosTheta;
+
+    arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
+}
+
+// Use the given verb, and points in the range [start, end) to insert a command into the SkPath.
+void PathResolver::addCommand(SkPath* outPath, char previousCmd,
+        char cmd, const std::vector<float>* points, size_t start, size_t end) {
+
+    int incr = 2;
+    float reflectiveCtrlPointX;
+    float reflectiveCtrlPointY;
+
+    switch (cmd) {
+    case 'z':
+    case 'Z':
+        outPath->close();
+        // Path is closed here, but we need to move the pen to the
+        // closed position. So we cache the segment's starting position,
+        // and restore it here.
+        currentX = currentSegmentStartX;
+        currentY = currentSegmentStartY;
+        ctrlPointX = currentSegmentStartX;
+        ctrlPointY = currentSegmentStartY;
+        outPath->moveTo(currentX, currentY);
+        break;
+    case 'm':
+    case 'M':
+    case 'l':
+    case 'L':
+    case 't':
+    case 'T':
+        incr = 2;
+        break;
+    case 'h':
+    case 'H':
+    case 'v':
+    case 'V':
+        incr = 1;
+        break;
+    case 'c':
+    case 'C':
+        incr = 6;
+        break;
+    case 's':
+    case 'S':
+    case 'q':
+    case 'Q':
+        incr = 4;
+        break;
+    case 'a':
+    case 'A':
+        incr = 7;
+        break;
+    }
+
+    for (unsigned int k = start; k < end; k += incr) {
+        switch (cmd) {
+        case 'm': // moveto - Start a new sub-path (relative)
+            currentX += points->at(k + 0);
+            currentY += points->at(k + 1);
+            if (k > start) {
+                // According to the spec, if a moveto is followed by multiple
+                // pairs of coordinates, the subsequent pairs are treated as
+                // implicit lineto commands.
+                outPath->rLineTo(points->at(k + 0), points->at(k + 1));
+            } else {
+                outPath->rMoveTo(points->at(k + 0), points->at(k + 1));
+                currentSegmentStartX = currentX;
+                currentSegmentStartY = currentY;
+            }
+            break;
+        case 'M': // moveto - Start a new sub-path
+            currentX = points->at(k + 0);
+            currentY = points->at(k + 1);
+            if (k > start) {
+                // According to the spec, if a moveto is followed by multiple
+                // pairs of coordinates, the subsequent pairs are treated as
+                // implicit lineto commands.
+                outPath->lineTo(points->at(k + 0), points->at(k + 1));
+            } else {
+                outPath->moveTo(points->at(k + 0), points->at(k + 1));
+                currentSegmentStartX = currentX;
+                currentSegmentStartY = currentY;
+            }
+            break;
+        case 'l': // lineto - Draw a line from the current point (relative)
+            outPath->rLineTo(points->at(k + 0), points->at(k + 1));
+            currentX += points->at(k + 0);
+            currentY += points->at(k + 1);
+            break;
+        case 'L': // lineto - Draw a line from the current point
+            outPath->lineTo(points->at(k + 0), points->at(k + 1));
+            currentX = points->at(k + 0);
+            currentY = points->at(k + 1);
+            break;
+        case 'h': // horizontal lineto - Draws a horizontal line (relative)
+            outPath->rLineTo(points->at(k + 0), 0);
+            currentX += points->at(k + 0);
+            break;
+        case 'H': // horizontal lineto - Draws a horizontal line
+            outPath->lineTo(points->at(k + 0), currentY);
+            currentX = points->at(k + 0);
+            break;
+        case 'v': // vertical lineto - Draws a vertical line from the current point (r)
+            outPath->rLineTo(0, points->at(k + 0));
+            currentY += points->at(k + 0);
+            break;
+        case 'V': // vertical lineto - Draws a vertical line from the current point
+            outPath->lineTo(currentX, points->at(k + 0));
+            currentY = points->at(k + 0);
+            break;
+        case 'c': // curveto - Draws a cubic Bézier curve (relative)
+            outPath->rCubicTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3),
+                    points->at(k + 4), points->at(k + 5));
+
+            ctrlPointX = currentX + points->at(k + 2);
+            ctrlPointY = currentY + points->at(k + 3);
+            currentX += points->at(k + 4);
+            currentY += points->at(k + 5);
+
+            break;
+        case 'C': // curveto - Draws a cubic Bézier curve
+            outPath->cubicTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3),
+                    points->at(k + 4), points->at(k + 5));
+            currentX = points->at(k + 4);
+            currentY = points->at(k + 5);
+            ctrlPointX = points->at(k + 2);
+            ctrlPointY = points->at(k + 3);
+            break;
+        case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
+            reflectiveCtrlPointX = 0;
+            reflectiveCtrlPointY = 0;
+            if (previousCmd == 'c' || previousCmd == 's'
+                    || previousCmd == 'C' || previousCmd == 'S') {
+                reflectiveCtrlPointX = currentX - ctrlPointX;
+                reflectiveCtrlPointY = currentY - ctrlPointY;
+            }
+            outPath->rCubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+                    points->at(k + 0), points->at(k + 1),
+                    points->at(k + 2), points->at(k + 3));
+            ctrlPointX = currentX + points->at(k + 0);
+            ctrlPointY = currentY + points->at(k + 1);
+            currentX += points->at(k + 2);
+            currentY += points->at(k + 3);
+            break;
+        case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
+            reflectiveCtrlPointX = currentX;
+            reflectiveCtrlPointY = currentY;
+            if (previousCmd == 'c' || previousCmd == 's'
+                    || previousCmd == 'C' || previousCmd == 'S') {
+                reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+                reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+            }
+            outPath->cubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+                    points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3));
+            ctrlPointX = points->at(k + 0);
+            ctrlPointY = points->at(k + 1);
+            currentX = points->at(k + 2);
+            currentY = points->at(k + 3);
+            break;
+        case 'q': // Draws a quadratic Bézier (relative)
+            outPath->rQuadTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3));
+            ctrlPointX = currentX + points->at(k + 0);
+            ctrlPointY = currentY + points->at(k + 1);
+            currentX += points->at(k + 2);
+            currentY += points->at(k + 3);
+            break;
+        case 'Q': // Draws a quadratic Bézier
+            outPath->quadTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3));
+            ctrlPointX = points->at(k + 0);
+            ctrlPointY = points->at(k + 1);
+            currentX = points->at(k + 2);
+            currentY = points->at(k + 3);
+            break;
+        case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
+            reflectiveCtrlPointX = 0;
+            reflectiveCtrlPointY = 0;
+            if (previousCmd == 'q' || previousCmd == 't'
+                    || previousCmd == 'Q' || previousCmd == 'T') {
+                reflectiveCtrlPointX = currentX - ctrlPointX;
+                reflectiveCtrlPointY = currentY - ctrlPointY;
+            }
+            outPath->rQuadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+                    points->at(k + 0), points->at(k + 1));
+            ctrlPointX = currentX + reflectiveCtrlPointX;
+            ctrlPointY = currentY + reflectiveCtrlPointY;
+            currentX += points->at(k + 0);
+            currentY += points->at(k + 1);
+            break;
+        case 'T': // Draws a quadratic Bézier curve (reflective control point)
+            reflectiveCtrlPointX = currentX;
+            reflectiveCtrlPointY = currentY;
+            if (previousCmd == 'q' || previousCmd == 't'
+                    || previousCmd == 'Q' || previousCmd == 'T') {
+                reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+                reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+            }
+            outPath->quadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+                    points->at(k + 0), points->at(k + 1));
+            ctrlPointX = reflectiveCtrlPointX;
+            ctrlPointY = reflectiveCtrlPointY;
+            currentX = points->at(k + 0);
+            currentY = points->at(k + 1);
+            break;
+        case 'a': // Draws an elliptical arc
+            // (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
+            drawArc(outPath,
+                    currentX,
+                    currentY,
+                    points->at(k + 5) + currentX,
+                    points->at(k + 6) + currentY,
+                    points->at(k + 0),
+                    points->at(k + 1),
+                    points->at(k + 2),
+                    points->at(k + 3) != 0,
+                    points->at(k + 4) != 0);
+            currentX += points->at(k + 5);
+            currentY += points->at(k + 6);
+            ctrlPointX = currentX;
+            ctrlPointY = currentY;
+            break;
+        case 'A': // Draws an elliptical arc
+            drawArc(outPath,
+                    currentX,
+                    currentY,
+                    points->at(k + 5),
+                    points->at(k + 6),
+                    points->at(k + 0),
+                    points->at(k + 1),
+                    points->at(k + 2),
+                    points->at(k + 3) != 0,
+                    points->at(k + 4) != 0);
+            currentX = points->at(k + 5);
+            currentY = points->at(k + 6);
+            ctrlPointX = currentX;
+            ctrlPointY = currentY;
+            break;
+        }
+        previousCmd = cmd;
+    }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/VectorDrawablePath.h b/libs/hwui/VectorDrawablePath.h
new file mode 100644
index 0000000..40ce986
--- /dev/null
+++ b/libs/hwui/VectorDrawablePath.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_VPATH_H
+#define ANDROID_HWUI_VPATH_H
+
+#include "SkPath.h"
+#include <vector>
+
+namespace android {
+namespace uirenderer {
+
+
+
+struct PathData {
+    // TODO: Try using FatVector instead of std::vector and do a micro benchmark on the performance
+    // difference.
+    std::vector<char> verbs;
+    std::vector<size_t> verbSizes;
+    std::vector<float> points;
+    bool operator== (const PathData& data) const {
+        return verbs == data.verbs && verbSizes == data.verbSizes && points == data.points;
+    }
+
+};
+
+class VectorDrawablePath {
+public:
+    VectorDrawablePath(const PathData& nodes);
+    VectorDrawablePath(const VectorDrawablePath& path);
+    VectorDrawablePath(const char* path, size_t strLength);
+    bool canMorph(const PathData& path);
+    bool canMorph(const VectorDrawablePath& path);
+    static void verbsToPath(SkPath* outPath, const PathData* data);
+    static void interpolatePaths(PathData* outPathData, const PathData* from, const PathData* to,
+            float fraction);
+private:
+    PathData mData;
+    SkPath mSkPath;
+};
+
+} // namespace uirenderer
+} // namespace android
+
+#endif // ANDROID_HWUI_VPATH_H
diff --git a/libs/hwui/microbench/OpReordererBench.cpp b/libs/hwui/microbench/OpReordererBench.cpp
index 7b8d0e5..b24858e 100644
--- a/libs/hwui/microbench/OpReordererBench.cpp
+++ b/libs/hwui/microbench/OpReordererBench.cpp
@@ -48,7 +48,7 @@
 void BM_OpReorderer_defer::Run(int iters) {
     StartBenchmarkTiming();
     for (int i = 0; i < iters; i++) {
-        OpReorderer reorderer(200, 200, *sReorderingDisplayList);
+        OpReorderer reorderer(200, 200, *sReorderingDisplayList, (Vector3) { 100, 100, 100 });
         MicroBench::DoNotOptimize(&reorderer);
     }
     StopBenchmarkTiming();
@@ -59,11 +59,13 @@
     TestUtils::runOnRenderThread([this, iters](renderthread::RenderThread& thread) {
         RenderState& renderState = thread.renderState();
         Caches& caches = Caches::getInstance();
+        BakedOpRenderer::LightInfo lightInfo = { 50.0f, 128, 128 };
+
         StartBenchmarkTiming();
         for (int i = 0; i < iters; i++) {
-            OpReorderer reorderer(200, 200, *sReorderingDisplayList);
+            OpReorderer reorderer(200, 200, *sReorderingDisplayList, (Vector3) { 100, 100, 100 });
 
-            BakedOpRenderer renderer(caches, renderState, true);
+            BakedOpRenderer renderer(caches, renderState, true, lightInfo);
             reorderer.replayBakedOps<BakedOpDispatcher>(renderer);
             MicroBench::DoNotOptimize(&renderer);
         }
diff --git a/libs/hwui/microbench/PathParserBench.cpp b/libs/hwui/microbench/PathParserBench.cpp
new file mode 100644
index 0000000..171078d
--- /dev/null
+++ b/libs/hwui/microbench/PathParserBench.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <benchmark/Benchmark.h>
+
+#include "PathParser.h"
+
+#include <SkPath.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+BENCHMARK_NO_ARG(BM_PathParser_parseStringPath);
+void BM_PathParser_parseStringPath::Run(int iter) {
+    const char* pathString = "M 1 1 m 2 2, l 3 3 L 3 3 H 4 h4 V5 v5, Q6 6 6 6 q 6 6 6 6t 7 7 T 7 7 C 8 8 8 8 8 8 c 8 8 8 8 8 8 S 9 9 9 9 s 9 9 9 9 A 10 10 0 1 1 10 10 a 10 10 0 1 1 10 10";
+    SkPath skPath;
+    size_t length = strlen(pathString);
+    PathParser::ParseResult result;
+    StartBenchmarkTiming();
+    for (int i = 0; i < iter; i++) {
+        PathParser::parseStringForSkPath(&skPath, &result, pathString, length);
+    }
+    StopBenchmarkTiming();
+}
diff --git a/libs/hwui/microbench/how_to_run.txt b/libs/hwui/microbench/how_to_run.txt
new file mode 100755
index 0000000..e6f80b2
--- /dev/null
+++ b/libs/hwui/microbench/how_to_run.txt
@@ -0,0 +1,4 @@
+mmm -j8 frameworks/base/libs/hwui &&
+adb push $ANDROID_PRODUCT_OUT/data/local/tmp/hwuimicro \
+    /data/local/tmp/hwuimicro &&
+    adb shell /data/local/tmp/hwuimicro
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
new file mode 100644
index 0000000..6b44557
--- /dev/null
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "OffscreenBufferPool.h"
+
+#include "Caches.h"
+#include "Properties.h"
+#include "renderstate/RenderState.h"
+#include "utils/FatVector.h"
+
+#include <utils/Log.h>
+
+#include <GLES2/gl2.h>
+
+namespace android {
+namespace uirenderer {
+
+////////////////////////////////////////////////////////////////////////////////
+// OffscreenBuffer
+////////////////////////////////////////////////////////////////////////////////
+
+OffscreenBuffer::OffscreenBuffer(RenderState& renderState, Caches& caches,
+        uint32_t viewportWidth, uint32_t viewportHeight)
+        : renderState(renderState)
+        , viewportWidth(viewportWidth)
+        , viewportHeight(viewportHeight)
+        , texture(caches) {
+    texture.width = computeIdealDimension(viewportWidth);
+    texture.height = computeIdealDimension(viewportHeight);
+    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);
+    // 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);
+}
+
+void OffscreenBuffer::updateMeshFromRegion() {
+    // avoid T-junctions as they cause artifacts in between the resultant
+    // geometry when complex transforms occur.
+    // TODO: generate the safeRegion only if necessary based on drawing transform
+    Region safeRegion = Region::createTJunctionFreeRegion(region);
+
+    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);
+
+    FatVector<TextureVertex, 64> meshVector(count * 4); // uses heap if more than 64 vertices needed
+    TextureVertex* mesh = &meshVector[0];
+    for (size_t i = 0; i < count; i++) {
+        const android::Rect* r = &rects[i];
+
+        const float u1 = r->left * texX;
+        const float v1 = (viewportHeight - r->top) * texY;
+        const float u2 = r->right * texX;
+        const float v2 = (viewportHeight - r->bottom) * texY;
+
+        TextureVertex::set(mesh++, r->left, r->top, u1, v1);
+        TextureVertex::set(mesh++, r->right, r->top, u2, v1);
+        TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
+        TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
+    }
+    elementCount = count * 6;
+    renderState.meshState().genOrUpdateMeshBuffer(&vbo,
+            sizeof(TextureVertex) * count * 4,
+            &meshVector[0],
+            GL_DYNAMIC_DRAW); // TODO: GL_STATIC_DRAW if savelayer
+}
+
+uint32_t OffscreenBuffer::computeIdealDimension(uint32_t dimension) {
+    return uint32_t(ceilf(dimension / float(LAYER_SIZE)) * LAYER_SIZE);
+}
+
+OffscreenBuffer::~OffscreenBuffer() {
+    texture.deleteTexture();
+    renderState.meshState().deleteMeshBuffer(vbo);
+    elementCount = 0;
+    vbo = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// OffscreenBufferPool
+///////////////////////////////////////////////////////////////////////////////
+
+OffscreenBufferPool::OffscreenBufferPool()
+    : mMaxSize(Properties::layerPoolSize) {
+}
+
+OffscreenBufferPool::~OffscreenBufferPool() {
+    clear(); // TODO: unique_ptr?
+}
+
+int OffscreenBufferPool::Entry::compare(const Entry& lhs, const Entry& rhs) {
+    int deltaInt = int(lhs.width) - int(rhs.width);
+    if (deltaInt != 0) return deltaInt;
+
+    return int(lhs.height) - int(rhs.height);
+}
+
+void OffscreenBufferPool::clear() {
+    for (auto entry : mPool) {
+        delete entry.layer;
+    }
+    mPool.clear();
+    mSize = 0;
+}
+
+OffscreenBuffer* OffscreenBufferPool::get(RenderState& renderState,
+        const uint32_t width, const uint32_t height) {
+    OffscreenBuffer* layer = nullptr;
+
+    Entry entry(width, height);
+    auto iter = mPool.find(entry);
+
+    if (iter != mPool.end()) {
+        entry = *iter;
+        mPool.erase(iter);
+
+        layer = entry.layer;
+        layer->viewportWidth = width;
+        layer->viewportHeight = height;
+        mSize -= layer->getSizeInBytes();
+    } else {
+        layer = new OffscreenBuffer(renderState, Caches::getInstance(), width, height);
+    }
+
+    return layer;
+}
+
+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)) {
+        // resize in place
+        layer->viewportWidth = width;
+        layer->viewportHeight = height;
+        return layer;
+    }
+    putOrDelete(layer);
+    return get(renderState, width, height);
+}
+
+void OffscreenBufferPool::dump() {
+    for (auto entry : mPool) {
+        ALOGD("  Layer size %dx%d", entry.width, entry.height);
+    }
+}
+
+void OffscreenBufferPool::putOrDelete(OffscreenBuffer* layer) {
+    const uint32_t size = layer->getSizeInBytes();
+    // Don't even try to cache a layer that's bigger than the cache
+    if (size < mMaxSize) {
+        // TODO: Use an LRU
+        while (mSize + size > mMaxSize) {
+            OffscreenBuffer* victim = mPool.begin()->layer;
+            mSize -= victim->getSizeInBytes();
+            delete victim;
+            mPool.erase(mPool.begin());
+        }
+
+        // clear region, since it's no longer valid
+        layer->region.clear();
+
+        Entry entry(layer);
+
+        mPool.insert(entry);
+        mSize += size;
+    } else {
+        delete layer;
+    }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.h b/libs/hwui/renderstate/OffscreenBufferPool.h
new file mode 100644
index 0000000..fac6c35
--- /dev/null
+++ b/libs/hwui/renderstate/OffscreenBufferPool.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
+#define ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
+
+#include "Caches.h"
+#include "Texture.h"
+#include "utils/Macros.h"
+
+#include <ui/Region.h>
+
+#include <set>
+
+namespace android {
+namespace uirenderer {
+
+class RenderState;
+
+/**
+ * Lightweight alternative to Layer. Owns the persistent state of an offscreen render target, and
+ * encompasses enough information to draw it back on screen (minus paint properties, which are held
+ * by LayerOp).
+ *
+ * Has two distinct sizes - viewportWidth/viewportHeight describe content area,
+ * texture.width/.height are actual allocated texture size. Texture will tend to be larger than the
+ * viewport bounds, since textures are always allocated with width / height as a multiple of 64, for
+ * the purpose of improving reuse.
+ */
+class OffscreenBuffer {
+public:
+    OffscreenBuffer(RenderState& renderState, Caches& caches,
+            uint32_t viewportWidth, uint32_t viewportHeight);
+    ~OffscreenBuffer();
+
+    // must be called prior to rendering, to construct/update vertex buffer
+    void updateMeshFromRegion();
+
+    // Set by RenderNode for HW layers, TODO for clipped saveLayers
+    void setWindowTransform(const Matrix4& transform) {
+        inverseTransformInWindow.loadInverse(transform);
+    }
+
+    static uint32_t computeIdealDimension(uint32_t dimension);
+
+    uint32_t getSizeInBytes() { return texture.width * texture.height * 4; }
+
+    RenderState& renderState;
+
+    uint32_t viewportWidth;
+    uint32_t viewportHeight;
+    Texture texture;
+
+    // Portion of layer that has been drawn to. Used to minimize drawing area when
+    // drawing back to screen / parent FBO.
+    Region region;
+
+    Matrix4 inverseTransformInWindow;
+
+    // vbo / size of mesh
+    GLsizei elementCount = 0;
+    GLuint vbo = 0;
+};
+
+/**
+ * Pool of OffscreenBuffers allocated, but not currently in use.
+ */
+class OffscreenBufferPool {
+public:
+    OffscreenBufferPool();
+    ~OffscreenBufferPool();
+
+    WARN_UNUSED_RESULT OffscreenBuffer* get(RenderState& renderState,
+            const uint32_t width, const uint32_t height);
+
+    WARN_UNUSED_RESULT OffscreenBuffer* resize(OffscreenBuffer* layer,
+            const uint32_t width, const uint32_t height);
+
+    void putOrDelete(OffscreenBuffer* layer);
+
+    /**
+     * Clears the pool. This causes all layers to be deleted.
+     */
+    void clear();
+
+    /**
+     * Returns the maximum size of the pool in bytes.
+     */
+    uint32_t getMaxSize() { return mMaxSize; }
+
+    /**
+     * Returns the current size of the pool in bytes.
+     */
+    uint32_t getSize() { return mSize; }
+
+    size_t getCount() { return mPool.size(); }
+
+    /**
+     * Prints out the content of the pool.
+     */
+    void dump();
+private:
+    struct Entry {
+        Entry() {}
+
+        Entry(const uint32_t layerWidth, const uint32_t layerHeight)
+                : width(OffscreenBuffer::computeIdealDimension(layerWidth))
+                , height(OffscreenBuffer::computeIdealDimension(layerHeight)) {}
+
+        Entry(OffscreenBuffer* layer)
+                : layer(layer)
+                , width(layer->texture.width)
+                , height(layer->texture.height) {
+        }
+
+        static int compare(const Entry& lhs, const Entry& rhs);
+
+        bool operator==(const Entry& other) const {
+            return compare(*this, other) == 0;
+        }
+
+        bool operator!=(const Entry& other) const {
+            return compare(*this, other) != 0;
+        }
+
+        bool operator<(const Entry& other) const {
+            return Entry::compare(*this, other) < 0;
+        }
+
+        OffscreenBuffer* layer = nullptr;
+        uint32_t width = 0;
+        uint32_t height = 0;
+    }; // struct Entry
+
+    std::multiset<Entry> mPool;
+
+    uint32_t mSize = 0;
+    uint32_t mMaxSize;
+}; // class OffscreenBufferCache
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_OFFSCREEN_BUFFER_POOL_H
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 9637117..4fa8200 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -90,6 +90,8 @@
     }
 */
 
+    mLayerPool.clear();
+
     // TODO: reset all cached state in state objects
     std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext);
     mAssetAtlas.terminate();
@@ -106,6 +108,19 @@
     mStencil = nullptr;
 }
 
+void RenderState::flush(Caches::FlushMode mode) {
+    switch (mode) {
+        case Caches::FlushMode::Full:
+            // fall through
+        case Caches::FlushMode::Moderate:
+            // fall through
+        case Caches::FlushMode::Layers:
+            mLayerPool.clear();
+            break;
+    }
+    mCaches->flush(mode);
+}
+
 void RenderState::setViewport(GLsizei width, GLsizei height) {
     mViewportWidth = width;
     mViewportHeight = height;
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index 3cda170..dcd5ea6 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -21,6 +21,7 @@
 #include "Glop.h"
 #include "renderstate/Blend.h"
 #include "renderstate/MeshState.h"
+#include "renderstate/OffscreenBufferPool.h"
 #include "renderstate/PixelBufferState.h"
 #include "renderstate/Scissor.h"
 #include "renderstate/Stencil.h"
@@ -56,6 +57,8 @@
     void onGLContextCreated();
     void onGLContextDestroyed();
 
+    void flush(Caches::FlushMode flushMode);
+
     void setViewport(GLsizei width, GLsizei height);
     void getViewport(GLsizei* outWidth, GLsizei* outHeight);
 
@@ -97,6 +100,8 @@
     Scissor& scissor() { return *mScissor; }
     Stencil& stencil() { return *mStencil; }
 
+    OffscreenBufferPool& layerPool() { return mLayerPool; }
+
     void dump();
 
 private:
@@ -116,6 +121,8 @@
     Scissor* mScissor = nullptr;
     Stencil* mStencil = nullptr;
 
+    OffscreenBufferPool mLayerPool;
+
     AssetAtlas mAssetAtlas;
     std::set<Layer*> mActiveLayers;
     std::set<renderthread::CanvasContext*> mRegisteredContexts;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b6fecb4..89cadea 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -31,7 +31,6 @@
 #include "utils/TimeUtils.h"
 
 #if HWUI_NEW_OPS
-#include "BakedOpRenderer.h"
 #include "OpReorderer.h"
 #endif
 
@@ -44,6 +43,8 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 
+#include <cstdlib>
+
 #define TRIM_MEMORY_COMPLETE 80
 #define TRIM_MEMORY_UI_HIDDEN 20
 
@@ -148,13 +149,23 @@
 // TODO: don't pass viewport size, it's automatic via EGL
 void CanvasContext::setup(int width, int height, float lightRadius,
         uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
+#if HWUI_NEW_OPS
+    mLightInfo.lightRadius = lightRadius;
+    mLightInfo.ambientShadowAlpha = ambientShadowAlpha;
+    mLightInfo.spotShadowAlpha = spotShadowAlpha;
+#else
     if (!mCanvas) return;
     mCanvas->initLight(lightRadius, ambientShadowAlpha, spotShadowAlpha);
+#endif
 }
 
 void CanvasContext::setLightCenter(const Vector3& lightCenter) {
+#if HWUI_NEW_OPS
+    mLightCenter = lightCenter;
+#else
     if (!mCanvas) return;
     mCanvas->setLightCenter(lightCenter);
+#endif
 }
 
 void CanvasContext::setOpaque(bool opaque) {
@@ -338,9 +349,11 @@
     mEglManager.damageFrame(frame, dirty);
 
 #if HWUI_NEW_OPS
-    OpReorderer reorderer(mLayerUpdateQueue, dirty, frame.width(), frame.height(), mRenderNodes);
+    OpReorderer reorderer(mLayerUpdateQueue, dirty, frame.width(), frame.height(),
+            mRenderNodes, mLightCenter);
     mLayerUpdateQueue.clear();
-    BakedOpRenderer renderer(Caches::getInstance(), mRenderThread.renderState(), mOpaque);
+    BakedOpRenderer renderer(Caches::getInstance(), mRenderThread.renderState(),
+            mOpaque, mLightInfo);
     // TODO: profiler().draw(mCanvas);
     reorderer.replayBakedOps<BakedOpDispatcher>(renderer);
 
@@ -574,8 +587,12 @@
     // purposes when the frame is actually drawn
     node->setPropertyFieldsDirty(RenderNode::GENERIC);
 
+#if HWUI_NEW_OPS
+    LOG_ALWAYS_FATAL("unsupported");
+#else
     mCanvas->markLayersAsBuildLayers();
     mCanvas->flushLayerUpdates();
+#endif
 
     node->incStrong(nullptr);
     mPrefetechedLayers.insert(node);
@@ -597,7 +614,7 @@
         // Make sure to release all the textures we were owning as there won't
         // be another draw
         caches.textureCache.resetMarkInUse(this);
-        caches.flush(Caches::FlushMode::Layers);
+        mRenderThread.renderState().flush(Caches::FlushMode::Layers);
     }
 }
 
@@ -607,10 +624,10 @@
 
     ATRACE_CALL();
     if (level >= TRIM_MEMORY_COMPLETE) {
-        Caches::getInstance().flush(Caches::FlushMode::Full);
+        thread.renderState().flush(Caches::FlushMode::Full);
         thread.eglManager().destroy();
     } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
-        Caches::getInstance().flush(Caches::FlushMode::Moderate);
+        thread.renderState().flush(Caches::FlushMode::Moderate);
     }
 }
 
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index d656014..c3cfc94 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -27,6 +27,10 @@
 #include "renderthread/RenderTask.h"
 #include "renderthread/RenderThread.h"
 
+#if HWUI_NEW_OPS
+#include "BakedOpRenderer.h"
+#endif
+
 #include <cutils/compiler.h>
 #include <EGL/egl.h>
 #include <SkBitmap.h>
@@ -165,6 +169,11 @@
 
     bool mOpaque;
     OpenGLRenderer* mCanvas = nullptr;
+#if HWUI_NEW_OPS
+    BakedOpRenderer::LightInfo mLightInfo;
+    Vector3 mLightCenter = { 0, 0, 0 };
+#endif
+
     bool mHaveNewSurface = false;
     DamageAccumulator mDamageAccumulator;
     LayerUpdateQueue mLayerUpdateQueue;
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 485759b..78df297 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -17,15 +17,14 @@
 #include "EglManager.h"
 
 #include "Caches.h"
+#include "DeviceInfo.h"
 #include "Properties.h"
 #include "RenderThread.h"
 #include "renderstate/RenderState.h"
 #include "utils/StringUtils.h"
-
 #include <cutils/log.h>
 #include <cutils/properties.h>
 #include <EGL/eglext.h>
-
 #include <string>
 
 #define GLES_VERSION 2
@@ -129,12 +128,14 @@
     createContext();
     createPBufferSurface();
     makeCurrent(mPBufferSurface);
+    DeviceInfo::initialize();
     mRenderThread.renderState().onGLContextCreated();
     initAtlas();
 }
 
 void EglManager::initExtensions() {
-    StringCollection extensions(eglQueryString(mEglDisplay, EGL_EXTENSIONS));
+    auto extensions = StringUtils::split(
+            eglQueryString(mEglDisplay, EGL_EXTENSIONS));
     EglExtensions.bufferAge = extensions.has("EGL_EXT_buffer_age");
     EglExtensions.setDamage = extensions.has("EGL_KHR_partial_update");
     LOG_ALWAYS_FATAL_IF(!extensions.has("EGL_KHR_swap_buffers_with_damage"),
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index a1107f0..15ccd6a 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -563,7 +563,10 @@
 void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
     void* retval;
     task->setReturnPtr(&retval);
-    mRenderThread.queueAndWait(task);
+    SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
+    AutoMutex _lock(mSyncMutex);
+    mRenderThread.queue(&syncTask);
+    mSyncCondition.wait(mSyncMutex);
     return retval;
 }
 
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index d0e601e..338fab6 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -117,6 +117,9 @@
 
     DrawFrameTask mDrawFrameTask;
 
+    Mutex mSyncMutex;
+    Condition mSyncCondition;
+
     void destroyContext();
 
     void post(RenderTask* task);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 526a848..9fb30c9 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -25,7 +25,9 @@
 #include <gui/ISurfaceComposer.h>
 #include <gui/SurfaceComposerClient.h>
 #include <sys/resource.h>
+#include <utils/Condition.h>
 #include <utils/Log.h>
+#include <utils/Mutex.h>
 
 namespace android {
 namespace uirenderer {
@@ -325,10 +327,16 @@
 }
 
 void RenderThread::queueAndWait(RenderTask* task) {
-    SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
-    AutoMutex _lock(mSyncMutex);
+    // These need to be local to the thread to avoid the Condition
+    // signaling the wrong thread. The easiest way to achieve that is to just
+    // make this on the stack, although that has a slight cost to it
+    Mutex mutex;
+    Condition condition;
+    SignalingRenderTask syncTask(task, &mutex, &condition);
+
+    AutoMutex _lock(mutex);
     queue(&syncTask);
-    mSyncCondition.wait(mSyncMutex);
+    condition.wait(mutex);
 }
 
 void RenderThread::queueAtFront(RenderTask* task) {
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index d8c7e61..076e3d4 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -27,9 +27,7 @@
 #include <utils/Looper.h>
 #include <utils/Thread.h>
 
-#include <condition_variable>
 #include <memory>
-#include <mutex>
 #include <set>
 
 namespace android {
@@ -127,8 +125,6 @@
 
     nsecs_t mNextWakeup;
     TaskQueue mQueue;
-    Mutex mSyncMutex;
-    Condition mSyncCondition;
 
     DisplayInfo mDisplayInfo;
 
diff --git a/libs/hwui/tests/TreeContentAnimation.cpp b/libs/hwui/tests/TreeContentAnimation.cpp
index 29d9803..81bf9ed 100644
--- a/libs/hwui/tests/TreeContentAnimation.cpp
+++ b/libs/hwui/tests/TreeContentAnimation.cpp
@@ -408,7 +408,7 @@
 public:
     sp<RenderNode> card = TestUtils::createNode<TestCanvas>(0, 0, 200, 200, [] (TestCanvas& canvas) {
         canvas.drawColor(0xFF0000FF, SkXfermode::kSrcOver_Mode);
-    }, true);
+    }, TestUtils::getHwLayerSetupCallback());
     void createContent(int width, int height, TestCanvas* canvas) override {
         canvas->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode); // background
         canvas->drawRenderNode(card.get());
diff --git a/libs/hwui/unit_tests/BakedOpStateTests.cpp b/libs/hwui/unit_tests/BakedOpStateTests.cpp
index bc1b69f..4e00fb3 100644
--- a/libs/hwui/unit_tests/BakedOpStateTests.cpp
+++ b/libs/hwui/unit_tests/BakedOpStateTests.cpp
@@ -60,24 +60,21 @@
 TEST(BakedOpState, constructAndReject) {
     LinearAllocator allocator;
 
-    Matrix4 identity;
-    identity.loadIdentity();
-
     Matrix4 translate100x0;
     translate100x0.loadTranslate(100, 0, 0);
 
     SkPaint paint;
     {
         RectOp rejectOp(Rect(30, 40, 100, 200), translate100x0, Rect(0, 0, 100, 200), &paint);
-        auto snapshot = TestUtils::makeSnapshot(identity, Rect(0, 0, 100, 200));
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 200));
         BakedOpState* bakedOp = BakedOpState::tryConstruct(allocator, *snapshot, rejectOp);
 
         EXPECT_EQ(bakedOp, nullptr); // rejected by clip, so not constructed
         EXPECT_LE(allocator.usedSize(), 8u); // no significant allocation space used for rejected op
     }
     {
-        RectOp successOp(Rect(30, 40, 100, 200), identity, Rect(0, 0, 100, 200), &paint);
-        auto snapshot = TestUtils::makeSnapshot(identity, Rect(0, 0, 100, 200));
+        RectOp successOp(Rect(30, 40, 100, 200), Matrix4::identity(), Rect(0, 0, 100, 200), &paint);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 200));
         BakedOpState* bakedOp = BakedOpState::tryConstruct(allocator, *snapshot, successOp);
 
         EXPECT_NE(bakedOp, nullptr); // NOT rejected by clip, so will be constructed
@@ -85,5 +82,24 @@
     }
 }
 
+TEST(BakedOpState, oplessConstructAndReject) {
+    LinearAllocator allocator;
+    {
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 0, 0)); // empty
+        BakedOpState* bakedOp = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
+
+        EXPECT_EQ(bakedOp, nullptr); // rejected by clip, so not constructed
+        EXPECT_LE(allocator.usedSize(), 8u); // no significant allocation space used for rejected op
+    }
+    {
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 200));
+        BakedOpState* bakedOp = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
+
+        EXPECT_NE(bakedOp, nullptr); // NOT rejected by clip, so will be constructed
+        EXPECT_GT(allocator.usedSize(), 64u); // relatively large alloc for non-rejected op
+        EXPECT_EQ((ShadowOp*)0x1234, bakedOp->op);
+    }
+}
+
 }
 }
diff --git a/libs/hwui/unit_tests/DeviceInfoTests.cpp b/libs/hwui/unit_tests/DeviceInfoTests.cpp
new file mode 100644
index 0000000..17236bd
--- /dev/null
+++ b/libs/hwui/unit_tests/DeviceInfoTests.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <DeviceInfo.h>
+
+#include <gtest/gtest.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+TEST(DeviceInfo, basic) {
+    // can't assert state before init - another test may have initialized the singleton
+    DeviceInfo::initialize();
+    const DeviceInfo* di = DeviceInfo::get();
+    ASSERT_NE(nullptr, di) << "DeviceInfo initialization failed";
+    EXPECT_EQ(2048, di->maxTextureSize()) << "Max texture size didn't match";
+}
diff --git a/libs/hwui/unit_tests/LayerUpdateQueueTests.cpp b/libs/hwui/unit_tests/LayerUpdateQueueTests.cpp
index 9d625bc..ef205ec 100644
--- a/libs/hwui/unit_tests/LayerUpdateQueueTests.cpp
+++ b/libs/hwui/unit_tests/LayerUpdateQueueTests.cpp
@@ -32,7 +32,7 @@
 // sync node properties, so properties() reflects correct width and height
 static sp<RenderNode> createSyncedNode(uint32_t width, uint32_t height) {
     sp<RenderNode> node = TestUtils::createNode(0, 0, width, height);
-    TestUtils::syncNodePropertiesAndDisplayList(node);
+    TestUtils::syncHierarchyPropertiesAndDisplayList(node);
     return node;
 }
 
diff --git a/libs/hwui/unit_tests/OffscreenBufferPoolTests.cpp b/libs/hwui/unit_tests/OffscreenBufferPoolTests.cpp
new file mode 100644
index 0000000..ba92157
--- /dev/null
+++ b/libs/hwui/unit_tests/OffscreenBufferPoolTests.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <renderstate/OffscreenBufferPool.h>
+
+#include <unit_tests/TestUtils.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+TEST(OffscreenBuffer, computeIdealDimension) {
+    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(1));
+    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(31));
+    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(33));
+    EXPECT_EQ(64u, OffscreenBuffer::computeIdealDimension(64));
+    EXPECT_EQ(1024u, OffscreenBuffer::computeIdealDimension(1000));
+}
+
+TEST(OffscreenBuffer, construct) {
+    TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) {
+        OffscreenBuffer layer(thread.renderState(), Caches::getInstance(), 49u, 149u);
+        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 * 192u * 4u, layer.getSizeInBytes());
+    });
+}
+
+TEST(OffscreenBufferPool, construct) {
+    TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) {
+        OffscreenBufferPool pool;
+        EXPECT_EQ(0u, pool.getCount()) << "pool must be created empty";
+        EXPECT_EQ(0u, pool.getSize()) << "pool must be created empty";
+        EXPECT_EQ((uint32_t) Properties::layerPoolSize, pool.getMaxSize())
+                << "pool must read size from Properties";
+    });
+
+}
+
+TEST(OffscreenBufferPool, getPutClear) {
+    TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) {
+        OffscreenBufferPool pool;
+
+        auto layer = pool.get(thread.renderState(), 100u, 200u);
+        EXPECT_EQ(100u, layer->viewportWidth);
+        EXPECT_EQ(200u, layer->viewportHeight);
+
+        ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize());
+
+        pool.putOrDelete(layer);
+        ASSERT_EQ(layer->getSizeInBytes(), pool.getSize());
+
+        auto layer2 = pool.get(thread.renderState(), 102u, 202u);
+        EXPECT_EQ(layer, layer2) << "layer should be recycled";
+        ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer";
+
+        pool.putOrDelete(layer);
+        EXPECT_EQ(1u, pool.getCount());
+        pool.clear();
+        EXPECT_EQ(0u, pool.getSize());
+        EXPECT_EQ(0u, pool.getCount());
+    });
+}
+
+TEST(OffscreenBufferPool, resize) {
+    TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) {
+        OffscreenBufferPool pool;
+
+        auto layer = pool.get(thread.renderState(), 64u, 64u);
+
+        // resize in place
+        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);
+
+        // resized to use different object in pool
+        auto layer2 = pool.get(thread.renderState(), 128u, 128u);
+        pool.putOrDelete(layer2);
+        ASSERT_EQ(1u, pool.getCount());
+        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);
+
+        // original allocation now only thing in pool
+        EXPECT_EQ(1u, pool.getCount());
+        EXPECT_EQ(layer->getSizeInBytes(), pool.getSize());
+    });
+}
+
+TEST(OffscreenBufferPool, putAndDestroy) {
+    TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) {
+        OffscreenBufferPool pool;
+        // layer too big to return to the pool
+        // Note: this relies on the fact that the pool won't reject based on max texture size
+        auto hugeLayer = pool.get(thread.renderState(), pool.getMaxSize() / 64, 64);
+        EXPECT_GT(hugeLayer->getSizeInBytes(), pool.getMaxSize());
+        pool.putOrDelete(hugeLayer);
+        EXPECT_EQ(0u, pool.getCount()); // failed to put (so was destroyed instead)
+    });
+}
diff --git a/libs/hwui/unit_tests/OpReordererTests.cpp b/libs/hwui/unit_tests/OpReordererTests.cpp
index 09b10c3..a8c9bba 100644
--- a/libs/hwui/unit_tests/OpReordererTests.cpp
+++ b/libs/hwui/unit_tests/OpReordererTests.cpp
@@ -29,6 +29,14 @@
 namespace uirenderer {
 
 LayerUpdateQueue sEmptyLayerUpdateQueue;
+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
@@ -38,23 +46,23 @@
  * and allows Renderer vs Dispatching behavior to be merged.
  *
  * onXXXOp methods fail by default - tests should override ops they expect
- * startLayer fails by default - tests should override if expected
+ * startRepaintLayer fails by default - tests should override if expected
  * startFrame/endFrame do nothing by default - tests should override to intercept
  */
 class TestRendererBase {
 public:
     virtual ~TestRendererBase() {}
-    virtual OffscreenBuffer* createLayer(uint32_t, uint32_t) {
+    virtual OffscreenBuffer* startTemporaryLayer(uint32_t, uint32_t) {
         ADD_FAILURE() << "Layer creation not expected in this test";
         return nullptr;
     }
-    virtual void startLayer(OffscreenBuffer*) {
+    virtual void startRepaintLayer(OffscreenBuffer*, const Rect& repaintRect) {
         ADD_FAILURE() << "Layer repaint not expected in this test";
     }
     virtual void endLayer() {
         ADD_FAILURE() << "Layer updates not expected in this test";
     }
-    virtual void startFrame(uint32_t width, uint32_t height) {}
+    virtual void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) {}
     virtual void endFrame() {}
 
     // define virtual defaults for direct
@@ -82,40 +90,39 @@
     MAP_OPS(DISPATCHER_METHOD);
 };
 
-
 class FailRenderer : public TestRendererBase {};
 
-class SimpleTestRenderer : public TestRendererBase {
-public:
-    void startFrame(uint32_t width, uint32_t height) override {
-        EXPECT_EQ(0, mIndex++);
-        EXPECT_EQ(100u, width);
-        EXPECT_EQ(200u, height);
-    }
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        EXPECT_EQ(1, mIndex++);
-    }
-    void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
-        EXPECT_EQ(2, mIndex++);
-    }
-    void endFrame() override {
-        EXPECT_EQ(3, mIndex++);
-    }
-};
 TEST(OpReorderer, simple) {
+    class SimpleTestRenderer : public TestRendererBase {
+    public:
+        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
+            EXPECT_EQ(0, mIndex++);
+            EXPECT_EQ(100u, width);
+            EXPECT_EQ(200u, height);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(1, mIndex++);
+        }
+        void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(2, mIndex++);
+        }
+        void endFrame() override {
+            EXPECT_EQ(3, mIndex++);
+        }
+    };
+
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
         SkBitmap bitmap = TestUtils::createSkBitmap(25, 25);
         canvas.drawRect(0, 0, 100, 200, SkPaint());
         canvas.drawBitmap(bitmap, 10, 10, nullptr);
     });
-    OpReorderer reorderer(100, 200, *dl);
+    OpReorderer reorderer(100, 200, *dl, sLightCenter);
 
     SimpleTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex()); // 2 ops + start + end
 }
 
-
 TEST(OpReorderer, simpleRejection) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
@@ -123,24 +130,24 @@
         canvas.drawRect(0, 0, 400, 400, SkPaint());
         canvas.restore();
     });
-    OpReorderer reorderer(200, 200, *dl);
+    OpReorderer reorderer(200, 200, *dl, sLightCenter);
 
     FailRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
 }
 
-
-static int SIMPLE_BATCHING_LOOPS = 5;
-class SimpleBatchingTestRenderer : public TestRendererBase {
-public:
-    void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
-        EXPECT_TRUE(mIndex++ >= SIMPLE_BATCHING_LOOPS);
-    }
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        EXPECT_TRUE(mIndex++ < SIMPLE_BATCHING_LOOPS);
-    }
-};
 TEST(OpReorderer, simpleBatching) {
+    static int SIMPLE_BATCHING_LOOPS = 5;
+    class SimpleBatchingTestRenderer : public TestRendererBase {
+    public:
+        void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
+            EXPECT_TRUE(mIndex++ >= SIMPLE_BATCHING_LOOPS);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_TRUE(mIndex++ < SIMPLE_BATCHING_LOOPS);
+        }
+    };
+
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         SkBitmap bitmap = TestUtils::createSkBitmap(10, 10);
 
@@ -155,31 +162,32 @@
         canvas.restore();
     });
 
-    OpReorderer reorderer(200, 200, *dl);
+    OpReorderer reorderer(200, 200, *dl, sLightCenter);
 
     SimpleBatchingTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2 * SIMPLE_BATCHING_LOOPS, renderer.getIndex()); // 2 x loops ops, because no merging (TODO: force no merging)
 }
 
-class RenderNodeTestRenderer : public TestRendererBase {
-public:
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        switch(mIndex++) {
-        case 0:
-            EXPECT_EQ(Rect(0, 0, 200, 200), state.computedState.clippedBounds);
-            EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
-            break;
-        case 1:
-            EXPECT_EQ(Rect(50, 50, 150, 150), state.computedState.clippedBounds);
-            EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
-            break;
-        default:
-            ADD_FAILURE();
-        }
-    }
-};
 TEST(OpReorderer, renderNode) {
+    class RenderNodeTestRenderer : public TestRendererBase {
+    public:
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            switch(mIndex++) {
+            case 0:
+                EXPECT_EQ(Rect(0, 0, 200, 200), state.computedState.clippedBounds);
+                EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
+                break;
+            case 1:
+                EXPECT_EQ(Rect(50, 50, 150, 150), state.computedState.clippedBounds);
+                EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
+                break;
+            default:
+                ADD_FAILURE();
+            }
+        }
+    };
+
     sp<RenderNode> child = TestUtils::createNode<RecordingCanvas>(10, 10, 110, 110, [](RecordingCanvas& canvas) {
         SkPaint paint;
         paint.setColor(SK_ColorWHITE);
@@ -198,139 +206,131 @@
         canvas.restore();
     });
 
-    TestUtils::syncNodePropertiesAndDisplayList(child);
-    TestUtils::syncNodePropertiesAndDisplayList(parent);
-
-    std::vector< sp<RenderNode> > nodes;
-    nodes.push_back(parent.get());
-
-    OpReorderer reorderer(sEmptyLayerUpdateQueue,
-            SkRect::MakeWH(200, 200), 200, 200, nodes);
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            createSyncedNodeList(parent), sLightCenter);
 
     RenderNodeTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
 }
 
-class ClippedTestRenderer : public TestRendererBase {
-public:
-    void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
-        EXPECT_EQ(0, mIndex++);
-        EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clippedBounds);
-        EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clipRect);
-        EXPECT_TRUE(state.computedState.transform.isIdentity());
-    }
-};
 TEST(OpReorderer, clipped) {
+    class ClippedTestRenderer : public TestRendererBase {
+    public:
+        void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(0, mIndex++);
+            EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clippedBounds);
+            EXPECT_EQ(Rect(10, 20, 30, 40), state.computedState.clipRect);
+            EXPECT_TRUE(state.computedState.transform.isIdentity());
+        }
+    };
+
     sp<RenderNode> node = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [](RecordingCanvas& canvas) {
         SkBitmap bitmap = TestUtils::createSkBitmap(200, 200);
         canvas.drawBitmap(bitmap, 0, 0, nullptr);
     });
-    TestUtils::syncNodePropertiesAndDisplayList(node);
-    std::vector< sp<RenderNode> > nodes;
-    nodes.push_back(node.get());
 
     OpReorderer reorderer(sEmptyLayerUpdateQueue,
             SkRect::MakeLTRB(10, 20, 30, 40), // clip to small area, should see in receiver
-            200, 200, nodes);
+            200, 200, createSyncedNodeList(node), sLightCenter);
 
     ClippedTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
 }
 
-
-class SaveLayerSimpleTestRenderer : public TestRendererBase {
-public:
-    OffscreenBuffer* createLayer(uint32_t width, uint32_t height) override {
-        EXPECT_EQ(0, mIndex++);
-        EXPECT_EQ(180u, width);
-        EXPECT_EQ(180u, height);
-        return nullptr;
-    }
-    void endLayer() override {
-        EXPECT_EQ(2, mIndex++);
-    }
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        EXPECT_EQ(1, mIndex++);
-        EXPECT_EQ(Rect(10, 10, 190, 190), op.unmappedBounds);
-        EXPECT_EQ(Rect(0, 0, 180, 180), state.computedState.clippedBounds);
-        EXPECT_EQ(Rect(0, 0, 180, 180), state.computedState.clipRect);
-
-        Matrix4 expectedTransform;
-        expectedTransform.loadTranslate(-10, -10, 0);
-        EXPECT_MATRIX_APPROX_EQ(expectedTransform, state.computedState.transform);
-    }
-    void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-        EXPECT_EQ(3, mIndex++);
-        EXPECT_EQ(Rect(10, 10, 190, 190), state.computedState.clippedBounds);
-        EXPECT_EQ(Rect(0, 0, 200, 200), state.computedState.clipRect);
-        EXPECT_TRUE(state.computedState.transform.isIdentity());
-    }
-};
 TEST(OpReorderer, saveLayerSimple) {
+    class SaveLayerSimpleTestRenderer : public TestRendererBase {
+    public:
+        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
+            EXPECT_EQ(0, mIndex++);
+            EXPECT_EQ(180u, width);
+            EXPECT_EQ(180u, height);
+            return nullptr;
+        }
+        void endLayer() override {
+            EXPECT_EQ(2, mIndex++);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(1, mIndex++);
+            EXPECT_EQ(Rect(10, 10, 190, 190), op.unmappedBounds);
+            EXPECT_EQ(Rect(0, 0, 180, 180), state.computedState.clippedBounds);
+            EXPECT_EQ(Rect(0, 0, 180, 180), state.computedState.clipRect);
+
+            Matrix4 expectedTransform;
+            expectedTransform.loadTranslate(-10, -10, 0);
+            EXPECT_MATRIX_APPROX_EQ(expectedTransform, state.computedState.transform);
+        }
+        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(3, mIndex++);
+            EXPECT_EQ(Rect(10, 10, 190, 190), state.computedState.clippedBounds);
+            EXPECT_EQ(Rect(0, 0, 200, 200), state.computedState.clipRect);
+            EXPECT_TRUE(state.computedState.transform.isIdentity());
+        }
+    };
+
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
         canvas.saveLayerAlpha(10, 10, 190, 190, 128, SkCanvas::kClipToLayer_SaveFlag);
         canvas.drawRect(10, 10, 190, 190, SkPaint());
         canvas.restore();
     });
 
-    OpReorderer reorderer(200, 200, *dl);
+    OpReorderer reorderer(200, 200, *dl, sLightCenter);
 
     SaveLayerSimpleTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(4, renderer.getIndex());
 }
 
-
-/* saveLayer1 {rect1, saveLayer2 { rect2 } } will play back as:
- * - createLayer2, rect2 endLayer2
- * - createLayer1, rect1, drawLayer2, endLayer1
- * - startFrame, layerOp1, endFrame
- */
-class SaveLayerNestedTestRenderer : public TestRendererBase {
-public:
-    OffscreenBuffer* createLayer(uint32_t width, uint32_t height) override {
-        const int index = mIndex++;
-        if (index == 0) {
-            EXPECT_EQ(400u, width);
-            EXPECT_EQ(400u, height);
-            return (OffscreenBuffer*) 0x400;
-        } else if (index == 3) {
-            EXPECT_EQ(800u, width);
-            EXPECT_EQ(800u, height);
-            return (OffscreenBuffer*) 0x800;
-        } else { ADD_FAILURE(); }
-        return (OffscreenBuffer*) nullptr;
-    }
-    void endLayer() override {
-        int index = mIndex++;
-        EXPECT_TRUE(index == 2 || index == 6);
-    }
-    void startFrame(uint32_t width, uint32_t height) override {
-        EXPECT_EQ(7, mIndex++);
-    }
-    void endFrame() override {
-        EXPECT_EQ(9, mIndex++);
-    }
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        const int index = mIndex++;
-        if (index == 1) {
-            EXPECT_EQ(Rect(0, 0, 400, 400), op.unmappedBounds); // inner rect
-        } else if (index == 4) {
-            EXPECT_EQ(Rect(0, 0, 800, 800), op.unmappedBounds); // outer rect
-        } else { ADD_FAILURE(); }
-    }
-    void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-        const int index = mIndex++;
-        if (index == 5) {
-            EXPECT_EQ((OffscreenBuffer*)0x400, *op.layerHandle);
-            EXPECT_EQ(Rect(0, 0, 400, 400), op.unmappedBounds); // inner layer
-        } else if (index == 8) {
-            EXPECT_EQ((OffscreenBuffer*)0x800, *op.layerHandle);
-            EXPECT_EQ(Rect(0, 0, 800, 800), op.unmappedBounds); // outer layer
-        } else { ADD_FAILURE(); }
-    }
-};
 TEST(OpReorderer, saveLayerNested) {
+    /* saveLayer1 { rect1, saveLayer2 { rect2 } } will play back as:
+     * - startTemporaryLayer2, rect2 endLayer2
+     * - startTemporaryLayer1, rect1, drawLayer2, endLayer1
+     * - startFrame, layerOp1, endFrame
+     */
+    class SaveLayerNestedTestRenderer : public TestRendererBase {
+    public:
+        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
+            const int index = mIndex++;
+            if (index == 0) {
+                EXPECT_EQ(400u, width);
+                EXPECT_EQ(400u, height);
+                return (OffscreenBuffer*) 0x400;
+            } else if (index == 3) {
+                EXPECT_EQ(800u, width);
+                EXPECT_EQ(800u, height);
+                return (OffscreenBuffer*) 0x800;
+            } else { ADD_FAILURE(); }
+            return (OffscreenBuffer*) nullptr;
+        }
+        void endLayer() override {
+            int index = mIndex++;
+            EXPECT_TRUE(index == 2 || index == 6);
+        }
+        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
+            EXPECT_EQ(7, mIndex++);
+        }
+        void endFrame() override {
+            EXPECT_EQ(9, mIndex++);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            const int index = mIndex++;
+            if (index == 1) {
+                EXPECT_EQ(Rect(0, 0, 400, 400), op.unmappedBounds); // inner rect
+            } else if (index == 4) {
+                EXPECT_EQ(Rect(0, 0, 800, 800), op.unmappedBounds); // outer rect
+            } else { ADD_FAILURE(); }
+        }
+        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+            const int index = mIndex++;
+            if (index == 5) {
+                EXPECT_EQ((OffscreenBuffer*)0x400, *op.layerHandle);
+                EXPECT_EQ(Rect(0, 0, 400, 400), op.unmappedBounds); // inner layer
+            } else if (index == 8) {
+                EXPECT_EQ((OffscreenBuffer*)0x800, *op.layerHandle);
+                EXPECT_EQ(Rect(0, 0, 800, 800), op.unmappedBounds); // outer layer
+            } else { ADD_FAILURE(); }
+        }
+    };
+
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(800, 800, [](RecordingCanvas& canvas) {
         canvas.saveLayerAlpha(0, 0, 800, 800, 128, SkCanvas::kClipToLayer_SaveFlag);
         {
@@ -344,7 +344,7 @@
         canvas.restore();
     });
 
-    OpReorderer reorderer(800, 800, *dl);
+    OpReorderer reorderer(800, 800, *dl, sLightCenter);
 
     SaveLayerNestedTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
@@ -363,137 +363,144 @@
         canvas.restore();
         canvas.restore();
     });
-    OpReorderer reorderer(200, 200, *dl);
+    OpReorderer reorderer(200, 200, *dl, sLightCenter);
 
     FailRenderer renderer;
     // should see no ops, even within the layer, since the layer should be rejected
     reorderer.replayBakedOps<TestDispatcher>(renderer);
 }
 
-class HwLayerSimpleTestRenderer : public TestRendererBase {
-public:
-    void startLayer(OffscreenBuffer* offscreenBuffer) override {
-        EXPECT_EQ(0, mIndex++);
-        EXPECT_EQ(offscreenBuffer, (OffscreenBuffer*) 0x0124);
-    }
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        EXPECT_EQ(1, mIndex++);
+RENDERTHREAD_TEST(OpReorderer, hwLayerSimple) {
+    class HwLayerSimpleTestRenderer : public TestRendererBase {
+    public:
+        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
+            EXPECT_EQ(0, mIndex++);
+            EXPECT_EQ(100u, offscreenBuffer->viewportWidth);
+            EXPECT_EQ(100u, offscreenBuffer->viewportHeight);
+            EXPECT_EQ(Rect(25, 25, 75, 75), repaintRect);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(1, mIndex++);
 
-        EXPECT_TRUE(state.computedState.transform.isIdentity())
-                << "Transform should be reset within layer";
+            EXPECT_TRUE(state.computedState.transform.isIdentity())
+                    << "Transform should be reset within layer";
 
-        EXPECT_EQ(state.computedState.clipRect, Rect(25, 25, 75, 75))
-                << "Damage rect should be used to clip layer content";
-    }
-    void endLayer() override {
-        EXPECT_EQ(2, mIndex++);
-    }
-    void startFrame(uint32_t width, uint32_t height) override {
-        EXPECT_EQ(3, mIndex++);
-    }
-    void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-        EXPECT_EQ(4, mIndex++);
-    }
-    void endFrame() override {
-        EXPECT_EQ(5, mIndex++);
-    }
-};
-TEST(OpReorderer, hwLayerSimple) {
+            EXPECT_EQ(state.computedState.clipRect, Rect(25, 25, 75, 75))
+                    << "Damage rect should be used to clip layer content";
+        }
+        void endLayer() override {
+            EXPECT_EQ(2, mIndex++);
+        }
+        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
+            EXPECT_EQ(3, mIndex++);
+        }
+        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(4, mIndex++);
+        }
+        void endFrame() override {
+            EXPECT_EQ(5, mIndex++);
+        }
+    };
+
     sp<RenderNode> node = TestUtils::createNode<RecordingCanvas>(10, 10, 110, 110, [](RecordingCanvas& canvas) {
         SkPaint paint;
         paint.setColor(SK_ColorWHITE);
         canvas.drawRect(0, 0, 100, 100, paint);
-    });
-    node->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
-    node->setPropertyFieldsDirty(RenderNode::GENERIC);
-    OffscreenBuffer** bufferHandle = node->getLayerHandle();
-    *bufferHandle = (OffscreenBuffer*) 0x0124;
+    }, TestUtils::getHwLayerSetupCallback());
+    OffscreenBuffer** layerHandle = node->getLayerHandle();
 
-    TestUtils::syncNodePropertiesAndDisplayList(node);
+    // create RenderNode's layer here in same way prepareTree would
+    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
+    *layerHandle = &layer;
 
-    std::vector< sp<RenderNode> > nodes;
-    nodes.push_back(node.get());
+    auto syncedNodeList = createSyncedNodeList(node);
 
     // only enqueue partial damage
-    LayerUpdateQueue layerUpdateQueue;
+    LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
     layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(25, 25, 75, 75));
 
-    OpReorderer reorderer(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, nodes);
-
+    OpReorderer reorderer(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            syncedNodeList, sLightCenter);
     HwLayerSimpleTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(6, renderer.getIndex());
 
     // clean up layer pointer, so we can safely destruct RenderNode
-    *bufferHandle = nullptr;
+    *layerHandle = nullptr;
 }
 
+RENDERTHREAD_TEST(OpReorderer, hwLayerComplex) {
+    /* parentLayer { greyRect, saveLayer { childLayer { whiteRect } } } will play back as:
+     * - startRepaintLayer(child), rect(grey), endLayer
+     * - startTemporaryLayer, drawLayer(child), endLayer
+     * - startRepaintLayer(parent), rect(white), drawLayer(saveLayer), endLayer
+     * - startFrame, drawLayer(parent), endLayerb
+     */
+    class HwLayerComplexTestRenderer : public TestRendererBase {
+    public:
+        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) {
+            EXPECT_EQ(3, mIndex++); // savelayer first
+            return (OffscreenBuffer*)0xabcd;
+        }
+        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
+            int index = mIndex++;
+            if (index == 0) {
+                // starting inner layer
+                EXPECT_EQ(100u, offscreenBuffer->viewportWidth);
+                EXPECT_EQ(100u, offscreenBuffer->viewportHeight);
+            } else if (index == 6) {
+                // starting outer layer
+                EXPECT_EQ(200u, offscreenBuffer->viewportWidth);
+                EXPECT_EQ(200u, offscreenBuffer->viewportHeight);
+            } else { ADD_FAILURE(); }
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            int index = mIndex++;
+            if (index == 1) {
+                // inner layer's rect (white)
+                EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
+            } else if (index == 7) {
+                // outer layer's rect (grey)
+                EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
+            } else { ADD_FAILURE(); }
+        }
+        void endLayer() override {
+            int index = mIndex++;
+            EXPECT_TRUE(index == 2 || index == 5 || index == 9);
+        }
+        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
+            EXPECT_EQ(10, mIndex++);
+        }
+        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+            OffscreenBuffer* layer = *op.layerHandle;
+            int index = mIndex++;
+            if (index == 4) {
+                EXPECT_EQ(100u, layer->viewportWidth);
+                EXPECT_EQ(100u, layer->viewportHeight);
+            } else if (index == 8) {
+                EXPECT_EQ((OffscreenBuffer*)0xabcd, *op.layerHandle);
+            } else if (index == 11) {
+                EXPECT_EQ(200u, layer->viewportWidth);
+                EXPECT_EQ(200u, layer->viewportHeight);
+            } else { ADD_FAILURE(); }
+        }
+        void endFrame() override {
+            EXPECT_EQ(12, mIndex++);
+        }
+    };
 
-/* parentLayer { greyRect, saveLayer { childLayer { whiteRect } } } will play back as:
- * - startLayer(child), rect(grey), endLayer
- * - createLayer, drawLayer(child), endLayer
- * - startLayer(parent), rect(white), drawLayer(saveLayer), endLayer
- * - startFrame, drawLayer(parent), endLayerb
- */
-class HwLayerComplexTestRenderer : public TestRendererBase {
-public:
-    OffscreenBuffer* createLayer(uint32_t width, uint32_t height) {
-        EXPECT_EQ(3, mIndex++); // savelayer first
-        return (OffscreenBuffer*)0xabcd;
-    }
-    void startLayer(OffscreenBuffer* offscreenBuffer) override {
-        int index = mIndex++;
-        if (index == 0) {
-            // starting inner layer
-            EXPECT_EQ((OffscreenBuffer*)0x4567, offscreenBuffer);
-        } else if (index == 6) {
-            // starting outer layer
-            EXPECT_EQ((OffscreenBuffer*)0x0123, offscreenBuffer);
-        } else { ADD_FAILURE(); }
-    }
-    void onRectOp(const RectOp& op, const BakedOpState& state) override {
-        int index = mIndex++;
-        if (index == 1) {
-            // inner layer's rect (white)
-            EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
-        } else if (index == 7) {
-            // outer layer's rect (grey)
-            EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
-        } else { ADD_FAILURE(); }
-    }
-    void endLayer() override {
-        int index = mIndex++;
-        EXPECT_TRUE(index == 2 || index == 5 || index == 9);
-    }
-    void startFrame(uint32_t width, uint32_t height) override {
-        EXPECT_EQ(10, mIndex++);
-    }
-    void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
-        int index = mIndex++;
-        if (index == 4) {
-            EXPECT_EQ((OffscreenBuffer*)0x4567, *op.layerHandle);
-        } else if (index == 8) {
-            EXPECT_EQ((OffscreenBuffer*)0xabcd, *op.layerHandle);
-        } else if (index == 11) {
-            EXPECT_EQ((OffscreenBuffer*)0x0123, *op.layerHandle);
-        } else { ADD_FAILURE(); }
-    }
-    void endFrame() override {
-        EXPECT_EQ(12, mIndex++);
-    }
-};
-TEST(OpReorderer, hwLayerComplex) {
-    sp<RenderNode> child = TestUtils::createNode<RecordingCanvas>(50, 50, 150, 150, [](RecordingCanvas& canvas) {
+    auto child = TestUtils::createNode<RecordingCanvas>(50, 50, 150, 150,
+            [](RecordingCanvas& canvas) {
         SkPaint paint;
         paint.setColor(SK_ColorWHITE);
         canvas.drawRect(0, 0, 100, 100, paint);
-    });
-    child->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
-    child->setPropertyFieldsDirty(RenderNode::GENERIC);
-    *(child->getLayerHandle()) = (OffscreenBuffer*) 0x4567;
+    }, TestUtils::getHwLayerSetupCallback());
+    OffscreenBuffer childLayer(renderThread.renderState(), Caches::getInstance(), 100, 100);
+    *(child->getLayerHandle()) = &childLayer;
 
     RenderNode* childPtr = child.get();
-    sp<RenderNode> parent = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200, [childPtr](RecordingCanvas& canvas) {
+    auto parent = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
+            [childPtr](RecordingCanvas& canvas) {
         SkPaint paint;
         paint.setColor(SK_ColorDKGRAY);
         canvas.drawRect(0, 0, 200, 200, paint);
@@ -501,22 +508,18 @@
         canvas.saveLayerAlpha(50, 50, 150, 150, 128, SkCanvas::kClipToLayer_SaveFlag);
         canvas.drawRenderNode(childPtr);
         canvas.restore();
-    });
-    parent->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
-    parent->setPropertyFieldsDirty(RenderNode::GENERIC);
-    *(parent->getLayerHandle()) = (OffscreenBuffer*) 0x0123;
+    }, TestUtils::getHwLayerSetupCallback());
+    OffscreenBuffer parentLayer(renderThread.renderState(), Caches::getInstance(), 200, 200);
+    *(parent->getLayerHandle()) = &parentLayer;
 
-    TestUtils::syncNodePropertiesAndDisplayList(child);
-    TestUtils::syncNodePropertiesAndDisplayList(parent);
+    auto syncedList = createSyncedNodeList(parent);
 
-    std::vector< sp<RenderNode> > nodes;
-    nodes.push_back(parent.get());
-
-    LayerUpdateQueue layerUpdateQueue;
+    LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
     layerUpdateQueue.enqueueLayerWithDamage(child.get(), Rect(100, 100));
     layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(200, 200));
 
-    OpReorderer reorderer(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, nodes);
+    OpReorderer reorderer(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            syncedList, sLightCenter);
 
     HwLayerComplexTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
@@ -527,5 +530,329 @@
     *(parent->getLayerHandle()) = nullptr;
 }
 
+static void drawOrderedRect(RecordingCanvas* canvas, uint8_t expectedDrawOrder) {
+    SkPaint paint;
+    paint.setColor(SkColorSetARGB(256, 0, 0, expectedDrawOrder)); // order put in blue channel
+    canvas->drawRect(0, 0, 100, 100, paint);
+}
+static void drawOrderedNode(RecordingCanvas* canvas, uint8_t expectedDrawOrder, float z) {
+    auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100,
+            [expectedDrawOrder](RecordingCanvas& canvas) {
+        drawOrderedRect(&canvas, expectedDrawOrder);
+    });
+    node->mutateStagingProperties().setTranslationZ(z);
+    node->setPropertyFieldsDirty(RenderNode::TRANSLATION_Z);
+    canvas->drawRenderNode(node.get()); // canvas takes reference/sole ownership
+}
+TEST(OpReorderer, zReorder) {
+    class ZReorderTestRenderer : public TestRendererBase {
+    public:
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            int expectedOrder = SkColorGetB(op.paint->getColor()); // extract order from blue channel
+            EXPECT_EQ(expectedOrder, mIndex++) << "An op was drawn out of order";
+        }
+    };
+
+    auto parent = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100,
+            [](RecordingCanvas& canvas) {
+        drawOrderedNode(&canvas, 0, 10.0f); // in reorder=false at this point, so played inorder
+        drawOrderedRect(&canvas, 1);
+        canvas.insertReorderBarrier(true);
+        drawOrderedNode(&canvas, 6, 2.0f);
+        drawOrderedRect(&canvas, 3);
+        drawOrderedNode(&canvas, 4, 0.0f);
+        drawOrderedRect(&canvas, 5);
+        drawOrderedNode(&canvas, 2, -2.0f);
+        drawOrderedNode(&canvas, 7, 2.0f);
+        canvas.insertReorderBarrier(false);
+        drawOrderedRect(&canvas, 8);
+        drawOrderedNode(&canvas, 9, -10.0f); // in reorder=false at this point, so played inorder
+    });
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100,
+            createSyncedNodeList(parent), sLightCenter);
+
+    ZReorderTestRenderer renderer;
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(10, renderer.getIndex());
+};
+
+// creates a 100x100 shadow casting node with provided translationZ
+static sp<RenderNode> createWhiteRectShadowCaster(float translationZ) {
+    return TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100,
+            [](RecordingCanvas& canvas) {
+        SkPaint paint;
+        paint.setColor(SK_ColorWHITE);
+        canvas.drawRect(0, 0, 100, 100, paint);
+    }, [translationZ] (RenderProperties& properties) {
+        properties.setTranslationZ(translationZ);
+        properties.mutableOutline().setRoundRect(0, 0, 100, 100, 0.0f, 1.0f);
+        return RenderNode::GENERIC | RenderNode::TRANSLATION_Z;
+    });
+}
+
+TEST(OpReorderer, shadow) {
+    class ShadowTestRenderer : public TestRendererBase {
+    public:
+        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(0, mIndex++);
+            EXPECT_FLOAT_EQ(1.0f, op.casterAlpha);
+            EXPECT_TRUE(op.casterPath->isRect(nullptr));
+            EXPECT_MATRIX_APPROX_EQ(Matrix4::identity(), op.shadowMatrixXY);
+
+            Matrix4 expectedZ;
+            expectedZ.loadTranslate(0, 0, 5);
+            EXPECT_MATRIX_APPROX_EQ(expectedZ, op.shadowMatrixZ);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(1, mIndex++);
+        }
+    };
+
+    sp<RenderNode> parent = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
+            [] (RecordingCanvas& canvas) {
+        canvas.insertReorderBarrier(true);
+        canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
+    });
+
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            createSyncedNodeList(parent), sLightCenter);
+
+    ShadowTestRenderer renderer;
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(2, renderer.getIndex());
+}
+
+TEST(OpReorderer, shadowSaveLayer) {
+    class ShadowSaveLayerTestRenderer : public TestRendererBase {
+    public:
+        OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height) override {
+            EXPECT_EQ(0, mIndex++);
+            return nullptr;
+        }
+        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(1, mIndex++);
+            EXPECT_FLOAT_EQ(50, op.lightCenter.x);
+            EXPECT_FLOAT_EQ(40, op.lightCenter.y);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(2, mIndex++);
+        }
+        void endLayer() override {
+            EXPECT_EQ(3, mIndex++);
+        }
+        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(4, mIndex++);
+        }
+    };
+
+    sp<RenderNode> parent = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
+            [] (RecordingCanvas& canvas) {
+        // save/restore outside of reorderBarrier, so they don't get moved out of place
+        canvas.translate(20, 10);
+        int count = canvas.saveLayerAlpha(30, 50, 130, 150, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.insertReorderBarrier(true);
+        canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
+        canvas.insertReorderBarrier(false);
+        canvas.restoreToCount(count);
+    });
+
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            createSyncedNodeList(parent), (Vector3) { 100, 100, 100 });
+
+    ShadowSaveLayerTestRenderer renderer;
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(5, renderer.getIndex());
+}
+
+RENDERTHREAD_TEST(OpReorderer, shadowHwLayer) {
+    class ShadowHwLayerTestRenderer : public TestRendererBase {
+    public:
+        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
+            EXPECT_EQ(0, mIndex++);
+        }
+        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(1, mIndex++);
+            EXPECT_FLOAT_EQ(50, op.lightCenter.x);
+            EXPECT_FLOAT_EQ(40, op.lightCenter.y);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(2, mIndex++);
+        }
+        void endLayer() override {
+            EXPECT_EQ(3, mIndex++);
+        }
+        void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(4, mIndex++);
+        }
+    };
+
+    sp<RenderNode> parent = TestUtils::createNode<RecordingCanvas>(50, 60, 150, 160,
+            [] (RecordingCanvas& canvas) {
+        canvas.insertReorderBarrier(true);
+        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.translate(20, 10);
+        canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
+        canvas.restore();
+    }, TestUtils::getHwLayerSetupCallback());
+    OffscreenBuffer** layerHandle = parent->getLayerHandle();
+
+    // create RenderNode's layer here in same way prepareTree would, setting windowTransform
+    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
+    Matrix4 windowTransform;
+    windowTransform.loadTranslate(50, 60, 0); // total transform of layer's origin
+    layer.setWindowTransform(windowTransform);
+    *layerHandle = &layer;
+
+    auto syncedList = createSyncedNodeList(parent);
+    LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
+    layerUpdateQueue.enqueueLayerWithDamage(parent.get(), Rect(100, 100));
+    OpReorderer reorderer(layerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            syncedList, (Vector3) { 100, 100, 100 });
+
+    ShadowHwLayerTestRenderer renderer;
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(5, renderer.getIndex());
+
+    // clean up layer pointer, so we can safely destruct RenderNode
+    *layerHandle = nullptr;
+}
+
+TEST(OpReorderer, shadowLayering) {
+    class ShadowLayeringTestRenderer : public TestRendererBase {
+    public:
+        void onShadowOp(const ShadowOp& op, const BakedOpState& state) override {
+            int index = mIndex++;
+            EXPECT_TRUE(index == 0 || index == 1);
+        }
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            int index = mIndex++;
+            EXPECT_TRUE(index == 2 || index == 3);
+        }
+    };
+    sp<RenderNode> parent = TestUtils::createNode<RecordingCanvas>(0, 0, 200, 200,
+            [] (RecordingCanvas& canvas) {
+        canvas.insertReorderBarrier(true);
+        canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
+        canvas.drawRenderNode(createWhiteRectShadowCaster(5.0001f).get());
+    });
+
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            createSyncedNodeList(parent), sLightCenter);
+
+    ShadowLayeringTestRenderer renderer;
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(4, renderer.getIndex());
+}
+
+
+static void testProperty(TestUtils::PropSetupCallback propSetupCallback,
+        std::function<void(const RectOp&, const BakedOpState&)> opValidateCallback) {
+    class PropertyTestRenderer : public TestRendererBase {
+    public:
+        PropertyTestRenderer(std::function<void(const RectOp&, const BakedOpState&)> callback)
+                : mCallback(callback) {}
+        void onRectOp(const RectOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(mIndex++, 0);
+            mCallback(op, state);
+        }
+        std::function<void(const RectOp&, const BakedOpState&)> mCallback;
+    };
+
+    auto node = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100, [](RecordingCanvas& canvas) {
+        SkPaint paint;
+        paint.setColor(SK_ColorWHITE);
+        canvas.drawRect(0, 0, 100, 100, paint);
+    }, propSetupCallback);
+
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 200, 200,
+            createSyncedNodeList(node), sLightCenter);
+
+    PropertyTestRenderer renderer(opValidateCallback);
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(1, renderer.getIndex()) << "Should have seen one op";
+}
+
+TEST(OpReorderer, renderPropOverlappingRenderingAlpha) {
+    testProperty([](RenderProperties& properties) {
+        properties.setAlpha(0.5f);
+        properties.setHasOverlappingRendering(false);
+        return RenderNode::ALPHA | RenderNode::GENERIC;
+    }, [](const RectOp& op, const BakedOpState& state) {
+        EXPECT_EQ(0.5f, state.alpha) << "Alpha should be applied directly to op";
+    });
+}
+
+TEST(OpReorderer, renderPropClipping) {
+    testProperty([](RenderProperties& properties) {
+        properties.setClipToBounds(true);
+        properties.setClipBounds(Rect(10, 20, 300, 400));
+        return RenderNode::GENERIC;
+    }, [](const RectOp& op, const BakedOpState& state) {
+        EXPECT_EQ(Rect(10, 20, 100, 100), state.computedState.clippedBounds)
+                << "Clip rect should be intersection of node bounds and clip bounds";
+    });
+}
+
+TEST(OpReorderer, renderPropRevealClip) {
+    testProperty([](RenderProperties& properties) {
+        properties.mutableRevealClip().set(true, 50, 50, 25);
+        return RenderNode::GENERIC;
+    }, [](const RectOp& op, const BakedOpState& state) {
+        ASSERT_NE(nullptr, state.roundRectClipState);
+        EXPECT_TRUE(state.roundRectClipState->highPriority);
+        EXPECT_EQ(25, state.roundRectClipState->radius);
+        EXPECT_EQ(Rect(50, 50, 50, 50), state.roundRectClipState->innerRect);
+    });
+}
+
+TEST(OpReorderer, renderPropOutlineClip) {
+    testProperty([](RenderProperties& properties) {
+        properties.mutableOutline().setShouldClip(true);
+        properties.mutableOutline().setRoundRect(10, 20, 30, 40, 5.0f, 0.5f);
+        return RenderNode::GENERIC;
+    }, [](const RectOp& op, const BakedOpState& state) {
+        ASSERT_NE(nullptr, state.roundRectClipState);
+        EXPECT_FALSE(state.roundRectClipState->highPriority);
+        EXPECT_EQ(5, state.roundRectClipState->radius);
+        EXPECT_EQ(Rect(15, 25, 25, 35), state.roundRectClipState->innerRect);
+    });
+}
+
+TEST(OpReorderer, renderPropTransform) {
+    testProperty([](RenderProperties& properties) {
+        properties.setLeftTopRightBottom(10, 10, 110, 110);
+
+        SkMatrix staticMatrix = SkMatrix::MakeScale(1.2f, 1.2f);
+        properties.setStaticMatrix(&staticMatrix);
+
+        // ignored, since static overrides animation
+        SkMatrix animationMatrix = SkMatrix::MakeTrans(15, 15);
+        properties.setAnimationMatrix(&animationMatrix);
+
+        properties.setTranslationX(10);
+        properties.setTranslationY(20);
+        properties.setScaleX(0.5f);
+        properties.setScaleY(0.7f);
+        return RenderNode::GENERIC
+                | RenderNode::TRANSLATION_X | RenderNode::TRANSLATION_Y
+                | RenderNode::SCALE_X | RenderNode::SCALE_Y;
+    }, [](const RectOp& op, const BakedOpState& state) {
+        Matrix4 matrix;
+        matrix.loadTranslate(10, 10, 0); // left, top
+        matrix.scale(1.2f, 1.2f, 1); // static matrix
+        // ignore animation matrix, since static overrides it
+
+        // translation xy
+        matrix.translate(10, 20);
+
+        // scale xy (from default pivot - center)
+        matrix.translate(50, 50);
+        matrix.scale(0.5f, 0.7f, 1);
+        matrix.translate(-50, -50);
+        EXPECT_MATRIX_APPROX_EQ(matrix, state.computedState.transform)
+                << "Op draw matrix must match expected combination of transformation properties";
+    });
+}
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/unit_tests/PathParserTests.cpp b/libs/hwui/unit_tests/PathParserTests.cpp
new file mode 100644
index 0000000..c99d7b0
--- /dev/null
+++ b/libs/hwui/unit_tests/PathParserTests.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "PathParser.h"
+#include "VectorDrawablePath.h"
+
+#include <functional>
+
+namespace android {
+namespace uirenderer {
+
+struct TestData {
+    const char* pathString;
+    const PathData pathData;
+    const std::function<void(SkPath*)> skPathLamda;
+};
+
+const static TestData sTestDataSet[] = {
+    // TestData with scientific notation -2e3 etc.
+    {
+        // Path
+        "M2.000000,22.000000l20.000000,0.000000 1e0-2e3z",
+        {
+            // Verbs
+            {'M', 'l', 'z'},
+            // Verb sizes
+            {2, 4, 0},
+            // Points
+            {2, 22, 20, 0,  1, -2000},
+        },
+        [](SkPath* outPath) {
+            outPath->moveTo(2, 22);
+            outPath->rLineTo(20, 0);
+            outPath->rLineTo(1, -2000);
+            outPath->close();
+            outPath->moveTo(2, 22);
+        }
+    },
+
+    // Comprehensive data, containing all the verbs possible.
+    {
+        // Path
+        "M 1 1 m 2 2, l 3 3 L 3 3 H 4 h4 V5 v5, Q6 6 6 6 q 6 6 6 6t 7 7 T 7 7 C 8 8 8 8 8 8 c 8 8 8 8 8 8 S 9 9 9 9 s 9 9 9 9 A 10 10 0 1 1 10 10 a 10 10 0 1 1 10 10",
+        {
+            // Verbs
+            {'M', 'm', 'l', 'L', 'H', 'h', 'V', 'v', 'Q', 'q', 't', 'T', 'C', 'c', 'S', 's', 'A', 'a'},
+            // VerbSizes
+            {2, 2, 2, 2, 1, 1, 1, 1, 4, 4, 2, 2, 6, 6, 4, 4, 7, 7},
+            // Points
+            {1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 5.0, 5.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 7.0, 7.0, 7.0, 7.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 9.0, 9.0, 9.0, 9.0, 9.0, 9.0, 9.0, 9.0, 10.0, 10.0, 0.0, 1.0, 1.0, 10.0, 10.0, 10.0, 10.0, 0.0, 1.0, 1.0, 10.0, 10.0, }
+        },
+        [](SkPath* outPath) {
+            outPath->moveTo(1.0, 1.0);
+            outPath->rMoveTo(2.0, 2.0);
+            outPath->rLineTo(3.0, 3.0);
+            outPath->lineTo(3.0, 3.0);
+            outPath->lineTo(4.0, 3.0);
+            outPath->rLineTo(4.0, 0);
+            outPath->lineTo(8.0, 5.0);
+            outPath->rLineTo(0, 5.0);
+            outPath->quadTo(6.0, 6.0, 6.0, 6.0);
+            outPath->rQuadTo(6.0, 6.0, 6.0, 6.0);
+            outPath->rQuadTo(0.0, 0.0, 7.0, 7.0);
+            outPath->quadTo(26.0, 26.0, 7.0, 7.0);
+            outPath->cubicTo(8.0, 8.0, 8.0, 8.0, 8.0, 8.0);
+            outPath->rCubicTo(8.0, 8.0, 8.0, 8.0, 8.0, 8.0);
+            outPath->cubicTo(16.0, 16.0, 9.0, 9.0, 9.0, 9.0);
+            outPath->rCubicTo(0.0, 0.0, 9.0, 9.0, 9.0, 9.0);
+            outPath->cubicTo(18.447775037328352, 20.404243860300607, 17.998389141249767, 22.8911717921705, 16.737515350332117, 24.986664170401575);
+            outPath->cubicTo(15.476641559414468, 27.08215654863265, 13.489843598291483, 28.644011882390082, 11.155893964798905, 29.37447073281729);
+            outPath->cubicTo(8.821944331306327, 30.1049295832445, 6.299226382436471, 29.954422532383525, 4.0686829203897235, 28.951642951534332);
+            outPath->cubicTo(1.838139458342976, 27.94886337068514, 0.05113662931485696, 26.161860541657013, -0.9516429515343354, 23.931317079610267);
+            outPath->cubicTo(-1.9544225323835278, 21.70077361756352, -2.1049295832444987, 19.178055668693663, -1.37447073281729, 16.844106035201087);
+            outPath->cubicTo(-0.6440118823900814, 14.51015640170851, 0.9178434513673546, 12.523358440585524, 3.0133358295984305, 11.262484649667876);
+            outPath->cubicTo(5.108828207829506, 10.001610858750228, 7.5957561396993984, 9.552224962671648, 10.000000000000005, 10.0);
+            outPath->cubicTo(10.0, 7.348852265086975, 11.054287646850167, 4.803576729418881, 12.928932188134523, 2.9289321881345254);
+            outPath->cubicTo(14.803576729418879, 1.0542876468501696, 17.348852265086972, 4.870079381441987E-16, 19.999999999999996, 0.0);
+            outPath->cubicTo(22.65114773491302, -4.870079381441987E-16, 25.19642327058112, 1.0542876468501678, 27.071067811865476, 2.9289321881345227);
+            outPath->cubicTo(28.94571235314983, 4.803576729418878, 30.0, 7.348852265086974, 30.0, 9.999999999999998);
+            outPath->cubicTo(30.0, 12.651147734913023, 28.94571235314983, 15.19642327058112, 27.071067811865476, 17.071067811865476);
+            outPath->cubicTo(25.19642327058112, 18.94571235314983, 22.651147734913028, 20.0, 20.000000000000004, 20.0);
+        }
+    },
+
+    // Random long data
+    {
+        // Path
+        "M5.3,13.2c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,-0.2 -0.4,-0.7 -0.2,-1.0c1.3,-1.9 2.9,-3.4 4.9,-4.5c4.1,-2.2 9.3,-2.2 13.4,0.0c1.9,1.1 3.6,2.5 4.9,4.4c0.2,0.3 0.1,0.8 -0.2,1.0c-0.3,0.2 -0.8,0.1 -1.0,-0.2c-1.2,-1.7 -2.6,-3.0 -4.3,-4.0c-3.7,-2.0 -8.3,-2.0 -12.0,0.0c-1.7,0.9 -3.2,2.3 -4.3,4.0C5.7,13.1 5.5,13.2 5.3,13.2z",
+        {
+            // Verbs
+            {'M', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'C', 'z'},
+            // Verb sizes
+            {2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0},
+            // Points
+            {5.3, 13.2, -0.1, 0, -0.3, 0, -0.4, -0.1, -0.3, -0.2, -0.4, -0.7, -0.2, -1, 1.3, -1.9, 2.9, -3.4, 4.9, -4.5, 4.1, -2.2, 9.3, -2.2, 13.4, 0, 1.9, 1.1, 3.6, 2.5, 4.9, 4.4, 0.2, 0.3, 0.1, 0.8, -0.2, 1, -0.3, 0.2, -0.8, 0.1, -1, -0.2, -1.2, -1.7, -2.6, -3, -4.3, -4, -3.7, -2, -8.3, -2, -12, 0, -1.7, 0.9, -3.2, 2.3, -4.3, 4, 5.7, 13.1, 5.5, 13.2, 5.3, 13.2},
+        },
+        [](SkPath* outPath) {
+            outPath->moveTo(5.3, 13.2);
+            outPath->rCubicTo(-0.1, 0.0, -0.3, 0.0, -0.4, -0.1);
+            outPath->rCubicTo(-0.3, -0.2, -0.4, -0.7, -0.2, -1.0);
+            outPath->rCubicTo(1.3, -1.9, 2.9, -3.4, 4.9, -4.5);
+            outPath->rCubicTo(4.1, -2.2, 9.3, -2.2, 13.4, 0.0);
+            outPath->rCubicTo(1.9, 1.1, 3.6, 2.5, 4.9, 4.4);
+            outPath->rCubicTo(0.2, 0.3, 0.1, 0.8, -0.2, 1.0);
+            outPath->rCubicTo(-0.3, 0.2, -0.8, 0.1, -1.0, -0.2);
+            outPath->rCubicTo(-1.2, -1.7, -2.6, -3.0, -4.3, -4.0);
+            outPath->rCubicTo(-3.7, -2.0, -8.3, -2.0, -12.0, 0.0);
+            outPath->rCubicTo(-1.7, 0.9, -3.2, 2.3, -4.3, 4.0);
+            outPath->cubicTo(5.7, 13.1, 5.5, 13.2, 5.3, 13.2);
+            outPath->close();
+            outPath->moveTo(5.3, 13.2);
+        }
+    },
+
+    // Extreme case with numbers and decimal points crunched together
+    {
+        // Path
+        "l0.0.0.5.0.0.5-0.5.0.0-.5z",
+        {
+            // Verbs
+            {'l', 'z'},
+            // Verb sizes
+            {10, 0},
+            // Points
+            {0, 0, 0.5, 0, 0, 0.5, -0.5, 0, 0, -0.5},
+        },
+        [](SkPath* outPath) {
+            outPath->rLineTo(0.0, 0.0);
+            outPath->rLineTo(0.5, 0.0);
+            outPath->rLineTo(0.0, 0.5);
+            outPath->rLineTo(-0.5, 0.0);
+            outPath->rLineTo(0.0, -0.5);
+            outPath->close();
+            outPath->moveTo(0.0, 0.0);
+        }
+    },
+
+    // Empty test data
+    {
+        "",
+        {
+                // Verbs
+                {},
+                {},
+                {},
+        },
+        [](SkPath* outPath) {}
+    }
+
+};
+
+struct StringPath {
+    const char* stringPath;
+    bool isValid;
+};
+
+const StringPath sStringPaths[] = {
+    {"3e...3", false},
+    {"L.M.F.A.O", false},
+    {"m 1 1", true},
+    {"z", true},
+    {"1-2e34567", false}
+};
+
+TEST(PathParser, parseStringForData) {
+    for (TestData testData: sTestDataSet) {
+        PathParser::ParseResult result;
+        // Test generated path data against the given data.
+        PathData pathData;
+        size_t length = strlen(testData.pathString);
+        PathParser::getPathDataFromString(&pathData, &result, testData.pathString, length);
+        EXPECT_EQ(testData.pathData, pathData);
+    }
+
+    for (StringPath stringPath : sStringPaths) {
+        PathParser::ParseResult result;
+        PathData pathData;
+        SkPath skPath;
+        PathParser::getPathDataFromString(&pathData, &result,
+                stringPath.stringPath, strlen(stringPath.stringPath));
+        EXPECT_EQ(stringPath.isValid, !result.failureOccurred);
+    }
+}
+
+TEST(PathParser, createSkPathFromPathData) {
+    for (TestData testData: sTestDataSet) {
+        SkPath expectedPath;
+        testData.skPathLamda(&expectedPath);
+        SkPath actualPath;
+        VectorDrawablePath::verbsToPath(&actualPath, &testData.pathData);
+        EXPECT_EQ(expectedPath, actualPath);
+    }
+}
+
+TEST(PathParser, parseStringForSkPath) {
+    for (TestData testData: sTestDataSet) {
+        PathParser::ParseResult result;
+        size_t length = strlen(testData.pathString);
+        // Check the return value as well as the SkPath generated.
+        SkPath actualPath;
+        PathParser::parseStringForSkPath(&actualPath, &result, testData.pathString, length);
+        bool hasValidData = !result.failureOccurred;
+        EXPECT_EQ(hasValidData, testData.pathData.verbs.size() > 0);
+        SkPath expectedPath;
+        testData.skPathLamda(&expectedPath);
+        EXPECT_EQ(expectedPath, actualPath);
+    }
+
+    for (StringPath stringPath : sStringPaths) {
+        PathParser::ParseResult result;
+        SkPath skPath;
+        PathParser::parseStringForSkPath(&skPath, &result, stringPath.stringPath,
+                strlen(stringPath.stringPath));
+        EXPECT_EQ(stringPath.isValid, !result.failureOccurred);
+    }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/unit_tests/RecordingCanvasTests.cpp b/libs/hwui/unit_tests/RecordingCanvasTests.cpp
index dcf1f64..83b37ab 100644
--- a/libs/hwui/unit_tests/RecordingCanvasTests.cpp
+++ b/libs/hwui/unit_tests/RecordingCanvasTests.cpp
@@ -25,7 +25,7 @@
 
 static void playbackOps(const DisplayList& displayList,
         std::function<void(const RecordedOp&)> opReceiver) {
-    for (const DisplayList::Chunk& chunk : displayList.getChunks()) {
+    for (auto& chunk : displayList.getChunks()) {
         for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
             RecordedOp* op = displayList.getOps()[opIndex];
             opReceiver(*op);
@@ -224,5 +224,26 @@
     EXPECT_EQ(3, count);
 }
 
+TEST(RecordingCanvas, testReorderBarrier) {
+    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
+        canvas.drawRect(0, 0, 400, 400, SkPaint());
+        canvas.insertReorderBarrier(true);
+        canvas.insertReorderBarrier(false);
+        canvas.insertReorderBarrier(false);
+        canvas.insertReorderBarrier(true);
+        canvas.drawRect(0, 0, 400, 400, SkPaint());
+        canvas.insertReorderBarrier(false);
+    });
+
+    auto chunks = dl->getChunks();
+    EXPECT_EQ(0u, chunks[0].beginOpIndex);
+    EXPECT_EQ(1u, chunks[0].endOpIndex);
+    EXPECT_FALSE(chunks[0].reorderChildren);
+
+    EXPECT_EQ(1u, chunks[1].beginOpIndex);
+    EXPECT_EQ(2u, chunks[1].endOpIndex);
+    EXPECT_TRUE(chunks[1].reorderChildren);
+}
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/unit_tests/StringUtilsTests.cpp b/libs/hwui/unit_tests/StringUtilsTests.cpp
index 5174ae9..6b2e265 100644
--- a/libs/hwui/unit_tests/StringUtilsTests.cpp
+++ b/libs/hwui/unit_tests/StringUtilsTests.cpp
@@ -16,13 +16,13 @@
 
 #include <gtest/gtest.h>
 
-#include "utils/StringUtils.h"
+#include <utils/StringUtils.h>
 
-namespace android {
-namespace uirenderer {
+using namespace android;
+using namespace android::uirenderer;
 
 TEST(StringUtils, simpleBuildSet) {
-    StringCollection collection("a b c");
+    auto collection = StringUtils::split("a b c");
 
     EXPECT_TRUE(collection.has("a"));
     EXPECT_TRUE(collection.has("b"));
@@ -31,11 +31,8 @@
 }
 
 TEST(StringUtils, advancedBuildSet) {
-    StringCollection collection("GL_ext1 GL_ext2 GL_ext3");
+    auto collection = StringUtils::split("GL_ext1 GL_ext2 GL_ext3");
 
     EXPECT_TRUE(collection.has("GL_ext1"));
     EXPECT_FALSE(collection.has("GL_ext")); // string present, but not in list
 }
-
-};
-};
diff --git a/libs/hwui/unit_tests/TestUtils.h b/libs/hwui/unit_tests/TestUtils.h
index 770f413..38bafd5 100644
--- a/libs/hwui/unit_tests/TestUtils.h
+++ b/libs/hwui/unit_tests/TestUtils.h
@@ -16,6 +16,8 @@
 #ifndef TEST_UTILS_H
 #define TEST_UTILS_H
 
+#include <DeviceInfo.h>
+#include <DisplayList.h>
 #include <Matrix.h>
 #include <Rect.h>
 #include <RenderNode.h>
@@ -23,6 +25,12 @@
 #include <renderthread/RenderThread.h>
 #include <Snapshot.h>
 
+#if HWUI_NEW_OPS
+#include <RecordedOp.h>
+#else
+#include <DisplayListOp.h>
+#endif
+
 #include <memory>
 
 namespace android {
@@ -37,6 +45,20 @@
             && MathUtils::areEqual(a.right, b.right) \
             && MathUtils::areEqual(a.bottom, b.bottom));
 
+/**
+ * Like gtest's TEST, but runs on the RenderThread, and 'renderThread' is passed, in top level scope
+ * (for e.g. accessing its RenderState)
+ */
+#define RENDERTHREAD_TEST(test_case_name, test_name) \
+    class test_case_name##_##test_name##_RenderThreadTest { \
+    public: \
+        static void doTheThing(renderthread::RenderThread& renderThread); \
+    }; \
+    TEST(test_case_name, test_name) { \
+        TestUtils::runOnRenderThread(test_case_name##_##test_name##_RenderThreadTest::doTheThing); \
+    }; \
+    void test_case_name##_##test_name##_RenderThreadTest::doTheThing(renderthread::RenderThread& renderThread)
+
 class TestUtils {
 public:
     class SignalingDtor {
@@ -89,21 +111,38 @@
         return std::unique_ptr<DisplayList>(canvas.finishRecording());
     }
 
-    static sp<RenderNode> createNode(int left, int top, int right, int bottom, bool onLayer = false) {
+    typedef std::function<int(RenderProperties&)> PropSetupCallback;
+
+    static PropSetupCallback getHwLayerSetupCallback() {
+        static PropSetupCallback sLayerSetupCallback = [] (RenderProperties& properties) {
+            properties.mutateLayerProperties().setType(LayerType::RenderLayer);
+            return RenderNode::GENERIC;
+        };
+        return sLayerSetupCallback;
+    }
+
+    static sp<RenderNode> createNode(int left, int top, int right, int bottom,
+            PropSetupCallback propSetupCallback = nullptr) {
+#if HWUI_NULL_GPU
+        // if RenderNodes are being sync'd/used, device info will be needed, since
+        // DeviceInfo::maxTextureSize() affects layer property
+        DeviceInfo::initialize();
+#endif
+
         sp<RenderNode> node = new RenderNode();
         node->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom);
         node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-        if (onLayer) {
-            node->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
-            node->setPropertyFieldsDirty(RenderNode::GENERIC);
+        if (propSetupCallback) {
+            node->setPropertyFieldsDirty(propSetupCallback(node->mutateStagingProperties()));
         }
         return node;
     }
 
     template<class CanvasType>
     static sp<RenderNode> createNode(int left, int top, int right, int bottom,
-            std::function<void(CanvasType& canvas)> canvasCallback, bool onLayer = false) {
-        sp<RenderNode> node = createNode(left, top, right, bottom, onLayer);
+            std::function<void(CanvasType& canvas)> canvasCallback,
+            PropSetupCallback propSetupCallback = nullptr) {
+        sp<RenderNode> node = createNode(left, top, right, bottom, propSetupCallback);
 
         auto&& props = node->stagingProperties(); // staging, since not sync'd yet
         CanvasType canvas(props.getWidth(), props.getHeight());
@@ -112,9 +151,8 @@
         return node;
     }
 
-    static void syncNodePropertiesAndDisplayList(sp<RenderNode>& node) {
-        node->syncProperties();
-        node->syncDisplayList();
+    static void syncHierarchyPropertiesAndDisplayList(sp<RenderNode>& node) {
+        syncHierarchyPropertiesAndDisplayListImpl(node.get());
     }
 
     typedef std::function<void(renderthread::RenderThread& thread)> RtCallback;
@@ -142,6 +180,18 @@
         TestTask task(rtCallback);
         renderthread::RenderThread::getInstance().queueAndWait(&task);
     }
+private:
+    static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
+        node->syncProperties();
+        node->syncDisplayList();
+        auto displayList = node->getDisplayList();
+        if (displayList) {
+            for (auto&& childOp : displayList->getChildren()) {
+                syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
+            }
+        }
+    }
+
 }; // class TestUtils
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/utils/FatVector.h b/libs/hwui/utils/FatVector.h
index 315c249..93d37c2 100644
--- a/libs/hwui/utils/FatVector.h
+++ b/libs/hwui/utils/FatVector.h
@@ -29,6 +29,7 @@
 #include "utils/Macros.h"
 
 #include <stddef.h>
+#include <stdlib.h>
 #include <type_traits>
 #include <utils/Log.h>
 
@@ -95,6 +96,7 @@
     FatVector(size_t capacity) : FatVector() {
         this->resize(capacity);
     }
+
 private:
     typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
 };
diff --git a/libs/hwui/utils/Macros.h b/libs/hwui/utils/Macros.h
index 5ca9083..ccf2287 100644
--- a/libs/hwui/utils/Macros.h
+++ b/libs/hwui/utils/Macros.h
@@ -35,4 +35,7 @@
         static_assert(std::is_standard_layout<Type>::value, \
         #Type " must have standard layout")
 
+#define WARN_UNUSED_RESULT \
+    __attribute__((warn_unused_result))
+
 #endif /* MACROS_H */
diff --git a/libs/hwui/utils/StringUtils.cpp b/libs/hwui/utils/StringUtils.cpp
index a1df0e7..64a5970 100644
--- a/libs/hwui/utils/StringUtils.cpp
+++ b/libs/hwui/utils/StringUtils.cpp
@@ -19,21 +19,19 @@
 namespace android {
 namespace uirenderer {
 
-StringCollection::StringCollection(const char* spacedList) {
+unordered_string_set StringUtils::split(const char* spacedList) {
+    unordered_string_set set;
     const char* current = spacedList;
     const char* head = current;
     do {
         head = strchr(current, ' ');
         std::string s(current, head ? head - current : strlen(current));
         if (s.length()) {
-            mSet.insert(s);
+            set.insert(std::move(s));
         }
         current = head + 1;
     } while (head);
-}
-
-bool StringCollection::has(const char* s) {
-    return mSet.find(std::string(s)) != mSet.end();
+    return set;
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/utils/StringUtils.h b/libs/hwui/utils/StringUtils.h
index ef2a6d5..055869f 100644
--- a/libs/hwui/utils/StringUtils.h
+++ b/libs/hwui/utils/StringUtils.h
@@ -22,12 +22,16 @@
 namespace android {
 namespace uirenderer {
 
-class StringCollection {
+class unordered_string_set : public std::unordered_set<std::string> {
 public:
-    StringCollection(const char* spacedList);
-    bool has(const char* string);
-private:
-    std::unordered_set<std::string> mSet;
+    bool has(const char* str) {
+        return find(std::string(str)) != end();
+    }
+};
+
+class StringUtils {
+public:
+    static unordered_string_set split(const char* spacedList);
 };
 
 } /* namespace uirenderer */
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 6c224e5..478fd99 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2179,6 +2179,7 @@
     // in media/hardware/CryptoAPI.h !
     public static final int CRYPTO_MODE_UNENCRYPTED = 0;
     public static final int CRYPTO_MODE_AES_CTR     = 1;
+    public static final int CRYPTO_MODE_AES_CBC     = 2;
 
     /**
      * Metadata describing the structure of a (at least partially) encrypted
@@ -2186,27 +2187,14 @@
      * A buffer's data is considered to be partitioned into "subSamples",
      * each subSample starts with a (potentially empty) run of plain,
      * unencrypted bytes followed by a (also potentially empty) run of
-     * encrypted bytes.
-     * numBytesOfClearData can be null to indicate that all data is encrypted.
-     * This information encapsulates per-sample metadata as outlined in
-     * ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base media file format files".
+     * encrypted bytes. If pattern encryption applies, each of the latter runs
+     * is encrypted only partly, according to a repeating pattern of "encrypt"
+     * and "skip" blocks. numBytesOfClearData can be null to indicate that all
+     * data is encrypted. This information encapsulates per-sample metadata as
+     * outlined in ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base
+     * media file format files".
      */
     public final static class CryptoInfo {
-        public void set(
-                int newNumSubSamples,
-                @NonNull int[] newNumBytesOfClearData,
-                @NonNull int[] newNumBytesOfEncryptedData,
-                @NonNull byte[] newKey,
-                @NonNull byte[] newIV,
-                int newMode) {
-            numSubSamples = newNumSubSamples;
-            numBytesOfClearData = newNumBytesOfClearData;
-            numBytesOfEncryptedData = newNumBytesOfEncryptedData;
-            key = newKey;
-            iv = newIV;
-            mode = newMode;
-        }
-
         /**
          * The number of subSamples that make up the buffer's contents.
          */
@@ -2220,7 +2208,7 @@
          */
         public int[] numBytesOfEncryptedData;
         /**
-         * A 16-byte opaque key
+         * A 16-byte key id
          */
         public byte[] key;
         /**
@@ -2229,10 +2217,84 @@
         public byte[] iv;
         /**
          * The type of encryption that has been applied,
-         * see {@link #CRYPTO_MODE_UNENCRYPTED} and {@link #CRYPTO_MODE_AES_CTR}.
+         * see {@link #CRYPTO_MODE_UNENCRYPTED}, {@link #CRYPTO_MODE_AES_CTR}
+         * and {@link #CRYPTO_MODE_AES_CBC}
          */
         public int mode;
 
+        /**
+         * Metadata describing encryption pattern for the protected bytes in a subsample.
+         */
+        public final static class Pattern {
+            /**
+             * Number of blocks to be encrypted in the pattern. If zero, pattern
+             * encryption is inoperative.
+             */
+            private int mEncryptBlocks;
+
+            /**
+             * Number of blocks to be skipped (left clear) in the pattern. If zero,
+             * pattern encryption is inoperative.
+             */
+            private int mSkipBlocks;
+
+            /**
+             * Construct a sample encryption pattern given the number of blocks to
+             * encrypt and skip in the pattern.
+             */
+            public Pattern(int blocksToEncrypt, int blocksToSkip) {
+                set(blocksToEncrypt, blocksToSkip);
+            }
+
+            /**
+             * Set the number of blocks to encrypt and skip in a sample encryption
+             * pattern.
+             */
+            public void set(int blocksToEncrypt, int blocksToSkip) {
+                mEncryptBlocks = blocksToEncrypt;
+                mSkipBlocks = blocksToSkip;
+            }
+
+            /**
+             * Return the number of blocks to skip in a sample encryption pattern.
+             */
+            public int getSkipBlocks() {
+                return mSkipBlocks;
+            }
+
+            /**
+             * Return the number of blocks to encrypt in a sample encryption pattern.
+             */
+            public int getEncryptBlocks() {
+                return mEncryptBlocks;
+            }
+        };
+
+        /**
+         * The pattern applicable to the protected data in each subsample.
+         */
+        private Pattern pattern;
+
+        public void set(
+                int newNumSubSamples,
+                @NonNull int[] newNumBytesOfClearData,
+                @NonNull int[] newNumBytesOfEncryptedData,
+                @NonNull byte[] newKey,
+                @NonNull byte[] newIV,
+                int newMode) {
+            numSubSamples = newNumSubSamples;
+            numBytesOfClearData = newNumBytesOfClearData;
+            numBytesOfEncryptedData = newNumBytesOfEncryptedData;
+            key = newKey;
+            iv = newIV;
+            mode = newMode;
+            pattern = new Pattern(0, 0);
+        }
+
+        public void setPattern(Pattern newPattern) {
+            pattern = newPattern;
+        }
+
         @Override
         public String toString() {
             StringBuilder builder = new StringBuilder();
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index e0a8026..41b8ab2 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -44,7 +44,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -519,13 +518,10 @@
                     return;
                 }
 
-                List<MediaItem> data = list.getList();
+                List<MediaItem> data = list == null ? null : list.getList();
                 if (DBG) {
                     Log.d(TAG, "onLoadChildren for " + mServiceComponent + " id=" + parentId);
                 }
-                if (data == null) {
-                    data = Collections.emptyList();
-                }
 
                 // Check that the subscription is still subscribed.
                 final Subscription subscription = mSubscriptions.get(parentId);
@@ -730,10 +726,9 @@
          * Called when the list of children is loaded or updated.
          *
          * @param parentId The media id of the parent media item.
-         * @param children The children which were loaded.
+         * @param children The children which were loaded, or null if the id is invalid.
          */
-        public void onChildrenLoaded(@NonNull String parentId,
-                                     @NonNull List<MediaItem> children) {
+        public void onChildrenLoaded(@NonNull String parentId, List<MediaItem> children) {
         }
 
         /**
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 043b80e..6197c70 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -931,9 +931,7 @@
      *
      * @param rating The {@link TvContentRating} to check.
      * @return {@code true} if this object contains {@code rating}, {@code false} otherwise.
-     * @hide
      */
-    @SystemApi
     public final boolean contains(@NonNull TvContentRating rating) {
         Preconditions.checkNotNull(rating);
         if (!rating.getMainRating().equals(mRating)) {
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 1bb99ff..f2c6a6c 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -469,10 +469,6 @@
                 = new Result<List<MediaBrowser.MediaItem>>(parentId) {
             @Override
             void onResultSent(List<MediaBrowser.MediaItem> list) {
-                if (list == null) {
-                    throw new IllegalStateException("onLoadChildren sent null list for id "
-                            + parentId);
-                }
                 if (mConnections.get(connection.callbacks.asBinder()) != connection) {
                     if (DBG) {
                         Log.d(TAG, "Not sending onLoadChildren result for connection that has"
@@ -481,7 +477,8 @@
                     return;
                 }
 
-                final ParceledListSlice<MediaBrowser.MediaItem> pls = new ParceledListSlice(list);
+                final ParceledListSlice<MediaBrowser.MediaItem> pls =
+                        list == null ? null : new ParceledListSlice(list);
                 try {
                     connection.callbacks.onLoadChildren(parentId, pls);
                 } catch (RemoteException ex) {
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index e8f680f..49b579c 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -834,29 +834,36 @@
         env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V");
     CHECK(constructID != NULL);
 
-    jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
+    const char *defaultMsg = "Unknown Error";
 
     /* translate OS errors to Java API CryptoException errorCodes (which are positive) */
     switch (err) {
         case ERROR_DRM_NO_LICENSE:
             err = gCryptoErrorCodes.cryptoErrorNoKey;
+            defaultMsg = "Crypto key not available";
             break;
         case ERROR_DRM_LICENSE_EXPIRED:
             err = gCryptoErrorCodes.cryptoErrorKeyExpired;
+            defaultMsg = "License expired";
             break;
         case ERROR_DRM_RESOURCE_BUSY:
             err = gCryptoErrorCodes.cryptoErrorResourceBusy;
+            defaultMsg = "Resource busy or unavailable";
             break;
         case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
             err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection;
+            defaultMsg = "Required output protections are not active";
             break;
         case ERROR_DRM_SESSION_NOT_OPENED:
             err = gCryptoErrorCodes.cryptoErrorSessionNotOpened;
+            defaultMsg = "Attempted to use a closed session";
             break;
         default:  /* Other negative DRM error codes go out as is. */
             break;
     }
 
+    jstring msgObj = env->NewStringUTF(msg != NULL ? msg : defaultMsg);
+
     jthrowable exception =
         (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj);
 
diff --git a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
index b762059..b5731f0918 100644
--- a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
@@ -19,8 +19,8 @@
     <string name="backup_confirm_title" msgid="827563724209303345">"Copiere de rezervă completă"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restabilire completă"</string>
     <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unei copii de rezervă complete a tuturor datelor pe un computer desktop conectat. Doriți să permiteți acest lucru?\n\nDacă nu aţi solicitat dvs. copierea de rezervă, nu permiteți ca operațiunea să continue."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Creaţi copii de rezervă pentru datele dvs."</string>
-    <string name="deny_backup_button_label" msgid="6009119115581097708">"Nu creaţi copii de rezervă"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Creați copii de rezervă pentru datele dvs."</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Nu creați copii de rezervă"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"S-a solicitat o restabilire completă a tuturor datelor de pe un computer desktop conectat. Doriți să permiteți acest lucru?\n\nDacă nu dvs. aţi solicitat această restabilire, nu permiteți continuarea operațiunii. Acest proces va înlocui toate datele existente în prezent pe dispozitiv!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restabiliţi datele dvs."</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Nu restabiliţi"</string>
diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml
index e67c554..ccf1501 100644
--- a/packages/DefaultContainerService/AndroidManifest.xml
+++ b/packages/DefaultContainerService/AndroidManifest.xml
@@ -12,7 +12,9 @@
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
 
     <application android:label="@string/service_name"
-                 android:allowBackup="false">
+                 android:allowBackup="false"
+                 android:forceDeviceEncrypted="true"
+                 android:encryptionAware="true">
 
         <service android:name=".DefaultContainerService"
                  android:enabled="true"
diff --git a/packages/DocumentsUI/res/color/item_doc_grid_overlay.xml b/packages/DocumentsUI/res/color/item_doc_grid_border.xml
similarity index 76%
rename from packages/DocumentsUI/res/color/item_doc_grid_overlay.xml
rename to packages/DocumentsUI/res/color/item_doc_grid_border.xml
index bf19d4e..e144af8 100644
--- a/packages/DocumentsUI/res/color/item_doc_grid_overlay.xml
+++ b/packages/DocumentsUI/res/color/item_doc_grid_border.xml
@@ -16,13 +16,8 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:state_activated="true"
-        android:color="?android:attr/colorAccent"
-        android:alpha="0.1" />
-    <item
-        android:state_enabled="false"
-        android:color="?android:attr/colorBackground"
-        android:alpha="0.5" />
+        android:state_focused="true"
+        android:color="?android:attr/colorAccent"/>
     <item
         android:color="@android:color/transparent" />
 </selector>
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_grid_selection_check.png b/packages/DocumentsUI/res/drawable-hdpi/ic_grid_selection_check.png
deleted file mode 100644
index f3007c2..0000000
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_grid_selection_check.png b/packages/DocumentsUI/res/drawable-mdpi/ic_grid_selection_check.png
deleted file mode 100644
index 16f2ab9..0000000
--- a/packages/DocumentsUI/res/drawable-mdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_selection_check.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_selection_check.png
deleted file mode 100644
index 0885320..0000000
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_selection_check.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_selection_check.png
deleted file mode 100644
index 083bbcc..0000000
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxxhdpi/ic_grid_selection_check.png b/packages/DocumentsUI/res/drawable-xxxhdpi/ic_grid_selection_check.png
deleted file mode 100644
index 74b1ca5..0000000
--- a/packages/DocumentsUI/res/drawable-xxxhdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable/item_doc_grid_overlay.xml b/packages/DocumentsUI/res/drawable/item_doc_grid_border.xml
similarity index 78%
rename from packages/DocumentsUI/res/drawable/item_doc_grid_overlay.xml
rename to packages/DocumentsUI/res/drawable/item_doc_grid_border.xml
index 3f50fb9..db66094 100644
--- a/packages/DocumentsUI/res/drawable/item_doc_grid_overlay.xml
+++ b/packages/DocumentsUI/res/drawable/item_doc_grid_border.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?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.
@@ -16,5 +16,7 @@
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <solid android:color="@color/item_doc_grid_overlay" />
+    <stroke
+        android:width="2dp"
+        android:color="@color/item_doc_grid_border"/>
 </shape>
diff --git a/packages/DocumentsUI/res/drawable/item_doc_grid_overlay_icon.xml b/packages/DocumentsUI/res/drawable/item_doc_grid_overlay_icon.xml
deleted file mode 100644
index d40de1e..0000000
--- a/packages/DocumentsUI/res/drawable/item_doc_grid_overlay_icon.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
-    <item android:state_focused="true" android:state_activated="true" android:drawable="@drawable/ic_grid_selection_check" />
-    <item android:state_focused="false" android:state_activated="true" android:drawable="@drawable/ic_grid_selection_check" />
-    <item android:drawable="@android:color/transparent" />
-</selector>
diff --git a/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml b/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml
index 231e110..381e1c89 100644
--- a/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml
+++ b/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml
@@ -18,7 +18,8 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/item_doc_list_background"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:focusable="true">
 
     <View
         android:id="@+id/focus_indicator"
diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml
index 71e618b..1dfb34a 100644
--- a/packages/DocumentsUI/res/layout/item_doc_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml
@@ -14,130 +14,110 @@
      limitations under the License.
 -->
 
-<com.android.documentsui.GridItem xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/grid_item_height"
+    android:layout_height="wrap_content"
     android:layout_margin="@dimen/grid_item_margin"
-    android:background="@color/item_doc_grid_background">
+    android:background="@color/item_doc_grid_background"
+    android:focusable="true">
 
-    <ImageView
-        android:id="@+id/icon_thumb"
+    <!-- Main item thumbnail.  Comprised of two overlapping images, the
+         visibility of which is controlled by code in
+         DirectoryFragment.java. -->
+    <FrameLayout
+        android:id="@+id/thumbnail"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:scaleType="centerCrop"
-        android:contentDescription="@null" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical">
-
+        android:layout_height="wrap_content"
+        android:paddingBottom="8dp">
+      
+        <com.android.documentsui.GridItemThumbnail
+            android:id="@+id/icon_thumb"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scaleType="centerCrop"
+            android:contentDescription="@null" />
+  
         <ImageView
             android:id="@+id/icon_mime"
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1"
+            android:layout_height="wrap_content"
             android:scaleType="centerInside"
             android:contentDescription="@null" />
+        
+    </FrameLayout>
+  
+    <!-- Item nameplate.  Has a mime-type icon and some text fields (title,
+         size, mod-time, etc). -->
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/thumbnail"
+        android:layout_toEndOf="@android:id/icon1"
+        android:singleLine="true"
+        android:ellipsize="middle"
+        android:textAlignment="viewStart"
+        android:paddingEnd="12dp"
+        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+        android:textColor="@*android:color/primary_text_default_material_light" />
 
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="@color/item_doc_grid_protect_background"
-            android:orientation="vertical"
-            android:paddingStart="16dp"
-            android:paddingEnd="12dp"
-            android:paddingTop="8dp"
-            android:paddingBottom="8dp">
+    <TextView
+        android:id="@+id/size"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@android:id/title"
+        android:layout_toEndOf="@android:id/icon1"
+        android:paddingEnd="4dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:textAlignment="viewStart"
+        android:textAppearance="@android:style/TextAppearance.Material.Caption"
+        android:textColor="@*android:color/primary_text_default_material_light" />
 
-            <LinearLayout
-                android:id="@+id/line1"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center_vertical"
-                android:orientation="horizontal"
-                android:baselineAligned="false">
-
-                <TextView
-                    android:id="@android:id/title"
-                    android:layout_width="0dp"
-                    android:layout_height="wrap_content"
-                    android:layout_weight="1"
-                    android:singleLine="true"
-                    android:ellipsize="middle"
-                    android:textAlignment="viewStart"
-                    android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-                    android:textColor="@*android:color/primary_text_default_material_dark" />
-
-                <ImageView
-                    android:id="@android:id/icon1"
-                    android:layout_width="@dimen/root_icon_size"
-                    android:layout_height="@dimen/root_icon_size"
-                    android:layout_marginStart="8dp"
-                    android:scaleType="centerInside"
-                    android:contentDescription="@null" />
-
-            </LinearLayout>
-
-            <LinearLayout
-                android:id="@+id/line2"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center_vertical"
-                android:orientation="horizontal"
-                android:baselineAligned="false">
-
-                <TextView
-                    android:id="@+id/date"
-                    android:layout_width="0dp"
-                    android:layout_height="wrap_content"
-                    android:layout_weight="0.5"
-                    android:singleLine="true"
-                    android:ellipsize="end"
-                    android:textAlignment="viewStart"
-                    android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                    android:textColor="@*android:color/primary_text_default_material_dark" />
-
-                <TextView
-                    android:id="@+id/size"
-                    android:layout_width="0dp"
-                    android:layout_height="wrap_content"
-                    android:layout_weight="0.5"
-                    android:layout_marginStart="8dp"
-                    android:singleLine="true"
-                    android:ellipsize="end"
-                    android:textAlignment="viewStart"
-                    android:textAppearance="@android:style/TextAppearance.Material.Caption"
-                    android:textColor="@*android:color/primary_text_default_material_dark" />
-
-                <ImageView
-                    android:id="@android:id/icon2"
-                    android:layout_width="@dimen/root_icon_size"
-                    android:layout_height="@dimen/root_icon_size"
-                    android:layout_marginStart="8dp"
-                    android:scaleType="centerInside"
-                    android:contentDescription="@null"
-                    android:visibility="gone" />
-
-            </LinearLayout>
-
-        </LinearLayout>
-
-    </LinearLayout>
-
+    <TextView
+        android:id="@+id/date"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@android:id/title"
+        android:layout_toEndOf="@id/size"
+        android:paddingEnd="12dp"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:textAlignment="viewStart"
+        android:textAppearance="@android:style/TextAppearance.Material.Caption"
+        android:textColor="@*android:color/primary_text_default_material_light" />
+    
     <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:src="@drawable/item_doc_grid_overlay"
+        android:id="@android:id/icon1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="8dp"
+        android:layout_below="@id/thumbnail"
+        android:layout_alignParentLeft="true"
+        android:layout_alignBottom="@id/size"
+        android:layout_alignTop="@android:id/title"
+        android:scaleType="centerInside"
         android:contentDescription="@null"
+        android:paddingStart="12dp"
+        android:paddingEnd="8dp"/>
+
+    <!-- Use an explicit spacer so we can align things to it. -->
+    <Space
+        android:id="@+id/bottomPadding"
+        android:layout_width="match_parent"
+        android:layout_height="8dp"
+        android:layout_below="@id/size" />
+
+    <!-- An overlay that draws the item border when it is focused. -->
+    <View
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBottom="@id/bottomPadding"
+        android:layout_alignTop="@id/thumbnail"
+        android:layout_alignLeft="@id/thumbnail"
+        android:layout_alignRight="@id/thumbnail"
+        android:contentDescription="@null"
+        android:background="@drawable/item_doc_grid_border"
         android:duplicateParentState="true" />
 
-    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:src="@drawable/item_doc_grid_overlay_icon"
-        android:scaleType="center"
-        android:contentDescription="@null"
-        android:duplicateParentState="true" />
-
-</com.android.documentsui.GridItem>
+</RelativeLayout>
diff --git a/packages/DocumentsUI/res/layout/item_doc_list.xml b/packages/DocumentsUI/res/layout/item_doc_list.xml
index eba00a6..c409166 100644
--- a/packages/DocumentsUI/res/layout/item_doc_list.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_list.xml
@@ -18,7 +18,8 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/item_doc_list_background"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    android:focusable="true">
   
     <View
         android:id="@+id/focus_indicator"
diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml
index a376418..68c8b65 100644
--- a/packages/DocumentsUI/res/values/colors.xml
+++ b/packages/DocumentsUI/res/values/colors.xml
@@ -24,7 +24,7 @@
     
     <color name="directory_background">@*android:color/material_grey_300</color>
     <color name="item_doc_grid_background">@android:color/white</color>
-    <color name="item_doc_grid_protect_background">#88000000</color>
+    <color name="item_doc_grid_protect_background">@android:color/white</color>
     <color name="band_select_background">#88ffffff</color>
     <color name="band_select_border">#44000000</color>
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Events.java b/packages/DocumentsUI/src/com/android/documentsui/Events.java
index 49dae3d..1b5b60de 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Events.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Events.java
@@ -117,6 +117,8 @@
         public MotionInputEvent(MotionEvent event, RecyclerView view) {
             mEvent = event;
             mView = view;
+
+            // Consider determining position lazily as an optimization.
             View child = mView.findChildViewUnder(mEvent.getX(), mEvent.getY());
             mPosition = (child != null)
                     ? mView.getChildAdapterPosition(child)
diff --git a/packages/DocumentsUI/src/com/android/documentsui/GridItem.java b/packages/DocumentsUI/src/com/android/documentsui/GridItemThumbnail.java
similarity index 80%
rename from packages/DocumentsUI/src/com/android/documentsui/GridItem.java
rename to packages/DocumentsUI/src/com/android/documentsui/GridItemThumbnail.java
index 990dca7..38d6d72 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/GridItem.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/GridItemThumbnail.java
@@ -18,22 +18,21 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.widget.FrameLayout;
+import android.widget.ImageView;
 
 /**
- * A FrameLayout subclass used by DirectoryFragment. Ensures that the resulting grid item is always
- * square.
+ * Ensures that grid thumbnails are always square.
  */
-public class GridItem extends FrameLayout {
-    public GridItem(Context context) {
+public class GridItemThumbnail extends ImageView {
+    public GridItemThumbnail(Context context) {
         super(context);
     }
 
-    public GridItem(Context context, AttributeSet attrs) {
+    public GridItemThumbnail(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
-    public GridItem(Context context, AttributeSet attrs, int defStyle) {
+    public GridItemThumbnail(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 108d5e8..21420c8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -113,16 +113,6 @@
 import com.android.documentsui.BaseActivity.DocumentContext;
 import com.android.documentsui.BaseActivity.DocumentsIntent;
 import com.android.documentsui.ProviderExecutor.Preemptable;
-import com.android.documentsui.R.animator;
-import com.android.documentsui.R.attr;
-import com.android.documentsui.R.bool;
-import com.android.documentsui.R.dimen;
-import com.android.documentsui.R.drawable;
-import com.android.documentsui.R.id;
-import com.android.documentsui.R.layout;
-import com.android.documentsui.R.menu;
-import com.android.documentsui.R.plurals;
-import com.android.documentsui.R.string;
 import com.android.documentsui.RecentsProvider.StateColumns;
 import com.android.documentsui.dirlist.MultiSelectManager.Callback;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
@@ -184,7 +174,7 @@
     private Point mThumbSize;
     private DocumentsAdapter mAdapter;
     private LoaderCallbacks<DirectoryResult> mCallbacks;
-    private FragmentTuner mFragmentTuner;
+    private FragmentTuner mTuner;
     private DocumentClipper mClipper;
     // These are lazily initialized.
     private LinearLayoutManager mListLayout;
@@ -319,7 +309,7 @@
         super.onActivityCreated(savedInstanceState);
 
         final Context context = getActivity();
-        final State state = getDisplayState(DirectoryFragment.this);
+        final State state = getDisplayState();
 
         final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
         final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
@@ -381,7 +371,7 @@
         mType = getArguments().getInt(EXTRA_TYPE);
         mStateKey = buildStateKey(root, doc);
 
-        mFragmentTuner = FragmentTuner.pick(state);
+        mTuner = FragmentTuner.pick(state);
         mClipper = new DocumentClipper(context);
 
         if (mType == TYPE_RECENT_OPEN) {
@@ -485,7 +475,7 @@
             return;
         }
 
-        CopyService.start(getActivity(), getDisplayState(this).selectedDocumentsForCopy,
+        CopyService.start(getActivity(), getDisplayState().selectedDocumentsForCopy,
                 (DocumentStack) data.getParcelableExtra(Shared.EXTRA_STACK),
                 data.getIntExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_COPY));
     }
@@ -524,7 +514,7 @@
         checkNotNull(cursor, "Cursor cannot be null.");
         final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
         final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
-        if (isDocumentEnabled(docMimeType, docFlags)) {
+        if (mTuner.isDocumentEnabled(docMimeType, docFlags)) {
             final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
             ((BaseActivity) getActivity()).onDocumentPicked(doc, mModel);
             mSelectionManager.clearSelection();
@@ -540,7 +530,7 @@
         // Remember last scroll location
         final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
         getView().saveHierarchyState(container);
-        final State state = getDisplayState(this);
+        final State state = getDisplayState();
         state.dirState.put(mStateKey, container);
     }
 
@@ -562,7 +552,7 @@
 
     public void onUserModeChanged() {
         final ContentResolver resolver = getActivity().getContentResolver();
-        final State state = getDisplayState(this);
+        final State state = getDisplayState();
 
         final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
         final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
@@ -591,7 +581,7 @@
     }
 
     private void updateDisplayState() {
-        final State state = getDisplayState(this);
+        final State state = getDisplayState();
 
         if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return;
         mLastMode = state.derivedMode;
@@ -665,13 +655,13 @@
 
         @Override
         public boolean onBeforeItemStateChange(int position, boolean selected) {
-            // Directories cannot be checked
             if (selected) {
                 final Cursor cursor = mModel.getItem(position);
                 checkNotNull(cursor, "Cursor cannot be null.");
                 final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
                 final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
-                return isDocumentEnabled(docMimeType, docFlags);
+                return mTuner.canSelectType(docMimeType)
+                        && mTuner.isDocumentEnabled(docMimeType, docFlags);
             }
             return true;
         }
@@ -743,7 +733,7 @@
         private void updateActionMenu() {
             checkNotNull(mMenu);
             // Delegate update logic to our owning action, since specialized logic is desired.
-            mFragmentTuner.updateActionMenu(mMenu, mType, mNoDeleteCount == 0);
+            mTuner.updateActionMenu(mMenu, mType, mNoDeleteCount == 0);
             Menus.disableHiddenItems(mMenu);
         }
 
@@ -915,7 +905,7 @@
         new GetDocumentsTask() {
             @Override
             void onDocumentsReady(List<DocumentInfo> docs) {
-                getDisplayState(DirectoryFragment.this).selectedDocumentsForCopy = docs;
+                getDisplayState().selectedDocumentsForCopy = docs;
 
                 boolean directoryCopy = false;
                 for (DocumentInfo info : docs) {
@@ -931,8 +921,8 @@
         }.execute(selected);
     }
 
-    private static State getDisplayState(Fragment fragment) {
-        return ((BaseActivity) fragment.getActivity()).getDisplayState();
+    private State getDisplayState() {
+        return ((BaseActivity) getActivity()).getDisplayState();
     }
 
     // Provide a reference to the views for each data item
@@ -948,10 +938,6 @@
 
         public DocumentHolder(View view) {
             super(view);
-            // Setting this using android:focusable in the item layouts doesn't work for list items.
-            // So we set it here.  Note that touch mode focus is a separate issue - see
-            // View.setFocusableInTouchMode and View.isInTouchMode for more info.
-            view.setFocusable(true);
             view.setOnKeyListener(this);
         }
 
@@ -1027,7 +1013,7 @@
 
         @Override
         public DocumentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-            final State state = getDisplayState(DirectoryFragment.this);
+            final State state = getDisplayState();
             final LayoutInflater inflater = LayoutInflater.from(getContext());
             View item = null;
             switch (state.derivedMode) {
@@ -1070,8 +1056,7 @@
         public void onBindViewHolder(DocumentHolder holder, int position) {
 
             final Context context = getContext();
-            final State state = getDisplayState(DirectoryFragment.this);
-            final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+            final State state = getDisplayState();
             final RootsCache roots = DocumentsApplication.getRootsCache(context);
             final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
                     context, mThumbSize);
@@ -1095,14 +1080,12 @@
 
             holder.setSelected(isSelected(position));
 
-            final View line1 = itemView.findViewById(R.id.line1);
             final View line2 = itemView.findViewById(R.id.line2);
 
             final ImageView iconMime = (ImageView) itemView.findViewById(R.id.icon_mime);
             final ImageView iconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb);
             final TextView title = (TextView) itemView.findViewById(android.R.id.title);
             final ImageView icon1 = (ImageView) itemView.findViewById(android.R.id.icon1);
-            final ImageView icon2 = (ImageView) itemView.findViewById(android.R.id.icon2);
             final TextView summary = (TextView) itemView.findViewById(android.R.id.summary);
             final TextView date = (TextView) itemView.findViewById(R.id.date);
             final TextView size = (TextView) itemView.findViewById(R.id.size);
@@ -1121,7 +1104,7 @@
                     || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType);
             final boolean showThumbnail = supportsThumbnail && allowThumbnail && !mSvelteRecents;
 
-            final boolean enabled = isDocumentEnabled(docMimeType, docFlags);
+            final boolean enabled = mTuner.isDocumentEnabled(docMimeType, docFlags);
             final float iconAlpha = (state.derivedMode == MODE_LIST && !enabled) ? 0.5f : 1f;
 
             boolean cacheHit = false;
@@ -1155,13 +1138,14 @@
                         getDocumentIcon(mContext, docAuthority, docId, docMimeType, docIcon, state));
             }
 
-            boolean hasLine1 = false;
             boolean hasLine2 = false;
 
             final boolean hideTitle = (state.derivedMode == MODE_GRID) && mHideGridTitles;
             if (!hideTitle) {
                 title.setText(docDisplayName);
-                hasLine1 = true;
+                title.setVisibility(View.VISIBLE);
+            } else {
+                title.setVisibility(View.GONE);
             }
 
             Drawable iconDrawable = null;
@@ -1169,11 +1153,7 @@
                 // We've already had to enumerate roots before any results can
                 // be shown, so this will never block.
                 final RootInfo root = roots.getRootBlocking(docAuthority, docRootId);
-                if (state.derivedMode == MODE_GRID) {
-                    iconDrawable = root.loadGridIcon(mContext);
-                } else {
-                    iconDrawable = root.loadIcon(mContext);
-                }
+                iconDrawable = root.loadIcon(mContext);
 
                 if (summary != null) {
                     final boolean alwaysShowSummary = getResources()
@@ -1215,16 +1195,10 @@
             }
 
             if (icon1 != null) icon1.setVisibility(View.GONE);
-            if (icon2 != null) icon2.setVisibility(View.GONE);
 
             if (iconDrawable != null) {
-                if (hasLine1) {
-                    icon1.setVisibility(View.VISIBLE);
-                    icon1.setImageDrawable(iconDrawable);
-                } else {
-                    icon2.setVisibility(View.VISIBLE);
-                    icon2.setImageDrawable(iconDrawable);
-                }
+                icon1.setVisibility(View.VISIBLE);
+                icon1.setImageDrawable(iconDrawable);
             }
 
             if (docLastModified == -1) {
@@ -1246,9 +1220,6 @@
                 size.setVisibility(View.GONE);
             }
 
-            if (line1 != null) {
-                line1.setVisibility(hasLine1 ? View.VISIBLE : View.GONE);
-            }
             if (line2 != null) {
                 line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE);
             }
@@ -1258,7 +1229,6 @@
             iconMime.setAlpha(iconAlpha);
             iconThumb.setAlpha(iconAlpha);
             if (icon1 != null) icon1.setAlpha(iconAlpha);
-            if (icon2 != null) icon2.setAlpha(iconAlpha);
 
             if (DEBUG_ENABLE_DND) {
                 setupDragAndDropOnDocumentView(itemView, cursor);
@@ -1330,22 +1300,6 @@
         }
     }
 
-    private boolean isDocumentEnabled(String docMimeType, int docFlags) {
-        final State state = getDisplayState(DirectoryFragment.this);
-
-        // Directories are always enabled
-        if (Document.MIME_TYPE_DIR.equals(docMimeType)) {
-            return true;
-        }
-
-        // Read-only files are disabled when creating
-        if (state.action == ACTION_CREATE && (docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) {
-            return false;
-        }
-
-        return MimePredicate.mimeMatches(state.acceptMimes, docMimeType);
-    }
-
     private void copyFromClipboard() {
         new AsyncTask<Void, Void, List<DocumentInfo>>() {
 
@@ -1393,7 +1347,7 @@
             return;
         }
 
-        final DocumentStack curStack = getDisplayState(DirectoryFragment.this).stack;
+        final DocumentStack curStack = getDisplayState().stack;
         DocumentStack tmpStack = new DocumentStack();
         if (destination != null) {
             tmpStack.push(destination);
@@ -1590,7 +1544,7 @@
         if (docs.size() == 1) {
             final DocumentInfo doc = docs.get(0);
             return getDocumentIcon(getActivity(), doc.authority, doc.documentId,
-                    doc.mimeType, doc.icon, getDisplayState(this));
+                    doc.mimeType, doc.icon, getDisplayState());
         }
         return getActivity().getDrawable(R.drawable.ic_doc_generic);
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index 7e9bbe2..a0ff165 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -17,39 +17,104 @@
 package com.android.documentsui.dirlist;
 
 import static com.android.documentsui.State.ACTION_BROWSE;
+import static com.android.documentsui.State.ACTION_CREATE;
+import static com.android.documentsui.State.ACTION_GET_CONTENT;
 import static com.android.documentsui.State.ACTION_MANAGE;
+import static com.android.documentsui.State.ACTION_OPEN;
+import static com.android.documentsui.State.ACTION_OPEN_TREE;
 import static com.android.internal.util.Preconditions.checkArgument;
 
-import android.os.SystemProperties;
-import android.view.Menu;
-import android.view.MenuItem;
-
 import com.android.documentsui.Menus;
+import com.android.documentsui.MimePredicate;
 import com.android.documentsui.R;
 import com.android.documentsui.State;
 
+import android.os.SystemProperties;
+import android.provider.DocumentsContract.Document;
+import android.view.Menu;
+import android.view.MenuItem;
+
 /**
  * Providers support for specializing the DirectoryFragment to the "host" Activity.
  * Feel free to expand the role of this class to handle other specializations.
  */
 public abstract class FragmentTuner {
+
+    final State mState;
+
+    public FragmentTuner(State state) {
+        mState = state;
+    }
+
     public static FragmentTuner pick(State state) {
         switch (state.action) {
             case ACTION_BROWSE:
-                return new FilesTuner();
+                return new FilesTuner(state);
             case ACTION_MANAGE:
-                return new ManageTuner();
+                return new DownloadsTuner(state);
             default:
-                return new DocumentsTuner();
+                return new DocumentsTuner(state);
         }
     }
 
+
     public abstract void updateActionMenu(Menu menu, int dirType, boolean canDelete);
 
+    // Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
+    // A folder is enabled such that it may be double clicked, even in settings
+    // when the folder itself cannot be selected. This may also be true of container types.
+    public boolean canSelectType(String docMimeType) {
+        return true;
+    }
+
+    public boolean isDocumentEnabled(String docMimeType, int docFlags) {
+        if (isDirectory(docMimeType)) {
+            return true;
+        }
+
+        return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
+    }
+
     /**
      * Provides support for Platform specific specializations of DirectoryFragment.
      */
     private static final class DocumentsTuner extends FragmentTuner {
+
+        public DocumentsTuner(State state) {
+            super(state);
+        }
+
+        @Override
+        public boolean canSelectType(String docMimeType) {
+            switch (mState.action) {
+                case ACTION_OPEN:
+                case ACTION_CREATE:
+                case ACTION_GET_CONTENT:
+                    return !isDirectory(docMimeType);
+                case ACTION_OPEN_TREE:
+                    // In this case nothing *ever* is selectable...the expected user behavior is
+                    // they navigate *into* a folder, then click a confirmation button indicating
+                    // that the current directory is the directory they are picking.
+                    return false;
+            }
+            return true;
+        }
+
+        @Override
+        public boolean isDocumentEnabled(String docMimeType, int docFlags) {
+            // Directories are always enabled
+            if (isDirectory(docMimeType)) {
+                return true;
+            }
+
+            // Read-only files are disabled when creating
+            if (mState.action == ACTION_CREATE && (docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) {
+                return false;
+            }
+
+            return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
+        }
+
         @Override
         public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
 
@@ -77,7 +142,11 @@
     /**
      * Provides support for Platform specific specializations of DirectoryFragment.
      */
-    private static final class ManageTuner extends FragmentTuner {
+    private static final class DownloadsTuner extends FragmentTuner {
+
+        public DownloadsTuner(State state) {
+            super(state);
+        }
 
         @Override
         public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
@@ -107,6 +176,11 @@
      * Provides support for Files activity specific specializations of DirectoryFragment.
      */
     private static final class FilesTuner extends FragmentTuner {
+
+        public FilesTuner(State state) {
+            super(state);
+        }
+
         @Override
         public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
 
@@ -124,4 +198,8 @@
             Menus.disableHiddenItems(menu, copy, paste);
         }
     }
+
+    private static boolean isDirectory(String mimeType) {
+        return Document.MIME_TYPE_DIR.equals(mimeType);
+    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
index b5a3b93..65e1a28 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
@@ -41,11 +41,9 @@
 import android.view.MotionEvent;
 import android.view.View;
 
-import com.android.documentsui.Events;
-import com.android.documentsui.R;
 import com.android.documentsui.Events.InputEvent;
 import com.android.documentsui.Events.MotionInputEvent;
-import com.android.documentsui.R.drawable;
+import com.android.documentsui.R;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -89,9 +87,7 @@
      * @param mode Selection mode
      */
     public MultiSelectManager(final RecyclerView recyclerView, int mode) {
-        this(recyclerView.getAdapter(), mode);
-
-        mEnvironment = new RuntimeSelectionEnvironment(recyclerView);
+        this(recyclerView.getAdapter(), new RuntimeSelectionEnvironment(recyclerView), mode);
 
         if (mode == MODE_MULTIPLE) {
             mBandManager = new BandController();
@@ -138,16 +134,15 @@
 
     /**
      * Constructs a new instance with {@code adapter} and {@code helper}.
+     * @param runtimeSelectionEnvironment
      * @hide
      */
     @VisibleForTesting
-    MultiSelectManager(Adapter<?> adapter, int mode) {
-        checkNotNull(adapter, "'adapter' cannot be null.");
-
+    MultiSelectManager(Adapter<?> adapter, SelectionEnvironment environment, int mode) {
+        mAdapter = checkNotNull(adapter, "'adapter' cannot be null.");
+        mEnvironment = checkNotNull(environment, "'environment' cannot be null.");
         mSingleSelect = mode == MODE_SINGLE;
 
-        mAdapter = adapter;
-
         mAdapter.registerAdapterDataObserver(
                 new AdapterDataObserver() {
 
@@ -881,7 +876,7 @@
         void focusItem(int position);
     }
 
-    /** RvFacade implementation backed by good ol' RecyclerView. */
+    /** Recycler view facade implementation backed by good ol' RecyclerView. */
     private static final class RuntimeSelectionEnvironment implements SelectionEnvironment {
 
         private final RecyclerView mView;
@@ -1961,11 +1956,50 @@
             return false;
         }
 
-        int target = RecyclerView.NO_POSITION;
+        // Here we unpack information from the event and pass it to an more
+        // easily tested method....basically eliminating the need to synthesize
+        // events and views and so on in our tests.
+        int position = findTargetPosition(view, keyCode);
+        if (position == RecyclerView.NO_POSITION) {
+            // If there is no valid navigation target, don't handle the keypress.
+            return false;
+        }
+
+        return attemptChangePosition(position, event.isShiftPressed());
+    }
+
+    @VisibleForTesting
+    boolean attemptChangePosition(int targetPosition, boolean isShiftPressed) {
+        // Focus the new file.
+        mEnvironment.focusItem(targetPosition);
+
+        if (isShiftPressed) {
+            if (!hasSelection()) {
+                // If there is no selection, start a selection when the user presses shift-arrow.
+                toggleSelection(targetPosition);
+            } else if (!mSingleSelect) {
+                mRanger.snapSelection(targetPosition);
+                notifySelectionChanged();
+            } else {
+                // We're in single select and have an existing selection.
+                // Our best guess as to what the user would expect is to advance the selection.
+                clearSelection();
+                toggleSelection(targetPosition);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the adapter position that the key combo is targeted at.
+     */
+    private int findTargetPosition(View view, int keyCode) {
+        int position = RecyclerView.NO_POSITION;
         if (keyCode == KeyEvent.KEYCODE_MOVE_HOME) {
-            target = 0;
+            position = 0;
         } else if (keyCode == KeyEvent.KEYCODE_MOVE_END) {
-            target = mAdapter.getItemCount() - 1;
+            position = mAdapter.getItemCount() - 1;
         } else {
             // Find a navigation target based on the arrow key that the user pressed.  Ignore
             // navigation targets that aren't items in the recycler view.
@@ -1989,30 +2023,10 @@
                 // TargetView can be null, for example, if the user pressed <down> at the bottom of
                 // the list.
                 if (targetView != null) {
-                    target = mEnvironment.getAdapterPositionForChildView(targetView);
+                    position = mEnvironment.getAdapterPositionForChildView(targetView);
                 }
             }
         }
-
-        if (target == RecyclerView.NO_POSITION) {
-            // If there is no valid navigation target, don't handle the keypress.
-            return false;
-        }
-
-        // Focus the new file.
-        mEnvironment.focusItem(target);
-
-        if (event.isShiftPressed()) {
-            if (!hasSelection()) {
-                // If there is no selection, start a selection when the user presses shift-arrow.
-                toggleSelection(mEnvironment.getAdapterPositionForChildView(view));
-            }
-
-            mRanger.snapSelection(target);
-            notifySelectionChanged();
-        }
-
-        return true;
+        return position;
     }
-
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 501392c..723700d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -249,15 +249,6 @@
         }
     }
 
-    public Drawable loadGridIcon(Context context) {
-        if (derivedIcon != 0) {
-            return IconUtils.applyTintAttr(context, derivedIcon,
-                    android.R.attr.textColorPrimaryInverse);
-        } else {
-            return IconUtils.loadPackageIcon(context, authority, icon);
-        }
-    }
-
     public Drawable loadToolbarIcon(Context context) {
         if (derivedIcon != 0) {
             return IconUtils.applyTintAttr(context, derivedIcon,
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/CopyTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/CopyTest.java
index 6f1a89b..369ab7d 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/CopyTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/CopyTest.java
@@ -32,6 +32,8 @@
 import android.test.MoreAsserts;
 import android.test.ServiceTestCase;
 import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
 import com.android.documentsui.model.DocumentInfo;
@@ -52,6 +54,7 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+@MediumTest
 public class CopyTest extends ServiceTestCase<CopyService> {
 
     public CopyTest() {
@@ -89,9 +92,6 @@
         super.tearDown();
     }
 
-    /**
-     * Test copying a single file.
-     */
     public void testCopyFile() throws Exception {
         String srcPath = "/test0.txt";
         Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain",
@@ -131,9 +131,6 @@
         MoreAsserts.assertEquals("Moved file contents differ", testContent.getBytes(), dstContent);
     }
 
-    /**
-     * Test copying multiple files.
-     */
     public void testCopyMultipleFiles() throws Exception {
         String testContent[] = {
                 "The five boxing wizards jump quickly",
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
index 9060516..ba91c83 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
@@ -31,11 +31,13 @@
 import android.support.test.uiautomator.UiDevice;
 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 FilesActivityUiTest extends InstrumentationTestCase {
 
     private static final int TIMEOUT = 5000;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DirectoryFragmentModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DirectoryFragmentModelTest.java
index 746e2117..b250e5d 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DirectoryFragmentModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DirectoryFragmentModelTest.java
@@ -25,6 +25,7 @@
 import android.support.v7.widget.RecyclerView;
 import android.test.AndroidTestCase;
 import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.view.ViewGroup;
 
 import com.android.documentsui.DirectoryResult;
@@ -34,6 +35,7 @@
 
 import java.util.List;
 
+@SmallTest
 public class DirectoryFragmentModelTest extends AndroidTestCase {
 
     private static final int ITEM_COUNT = 5;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
index 24f5c9e..b3d45ae 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
@@ -18,12 +18,12 @@
 
 import android.support.v7.widget.RecyclerView;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.SparseBooleanArray;
 import android.view.View;
 import android.view.ViewGroup;
 
 import com.android.documentsui.TestInputEvent;
-import com.android.documentsui.dirlist.MultiSelectManager;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 
 import org.mockito.Mockito;
@@ -33,6 +33,7 @@
 import java.util.List;
 import java.util.Set;
 
+@SmallTest
 public class MultiSelectManagerTest extends AndroidTestCase {
 
     private static final List<String> items;
@@ -49,11 +50,13 @@
     private MultiSelectManager mManager;
     private TestAdapter mAdapter;
     private TestCallback mCallback;
+    private TestSelectionEnvironment mEnv;
 
     public void setUp() throws Exception {
         mAdapter = new TestAdapter(items);
         mCallback = new TestCallback();
-        mManager = new MultiSelectManager(mAdapter, MultiSelectManager.MODE_MULTIPLE);
+        mEnv = new TestSelectionEnvironment();
+        mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_MULTIPLE);
         mManager.addCallback(mCallback);
     }
 
@@ -162,7 +165,6 @@
         assertRangeSelection(14, 17);
     }
 
-
     public void testSingleTapUp_ShiftReversesSelectionDirection() {
         longPress(7);
         shiftTap(17);
@@ -171,7 +173,7 @@
     }
 
     public void testSingleSelectMode() {
-        mManager = new MultiSelectManager(mAdapter, MultiSelectManager.MODE_SINGLE);
+        mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_SINGLE);
         mManager.addCallback(mCallback);
         longPress(20);
         tap(13);
@@ -179,13 +181,21 @@
     }
 
     public void testSingleSelectMode_ShiftTap() {
-        mManager = new MultiSelectManager(mAdapter, MultiSelectManager.MODE_SINGLE);
+        mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_SINGLE);
         mManager.addCallback(mCallback);
         longPress(13);
         shiftTap(20);
         assertSelection(20);
     }
 
+    public void testSingleSelectMode_ShiftDoesNotExtendSelection() {
+        mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_SINGLE);
+        mManager.addCallback(mCallback);
+        longPress(20);
+        keyToPosition(22, true);
+        assertSelection(22);
+    }
+
     public void testProvisionalSelection() {
         Selection s = mManager.getSelection();
         assertSelection();
@@ -235,6 +245,10 @@
         mManager.onSingleTapUp(TestInputEvent.shiftClick(position));
     }
 
+    private void keyToPosition(int position, boolean shift) {
+        mManager.attemptChangePosition(position, shift);
+    }
+
     private void assertSelected(int... expected) {
         for (int i = 0; i < expected.length; i++) {
             Selection selection = mManager.getSelection();
@@ -290,11 +304,8 @@
 
     private static final class TestHolder extends RecyclerView.ViewHolder {
         // each data item is just a string in this case
-        public View view;
-        public String string;
         public TestHolder(View view) {
             super(view);
-            this.view = view;
         }
     }
 
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java
index c4b6ce5..c856b22 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java
@@ -20,11 +20,13 @@
 import android.graphics.Rect;
 import android.support.v7.widget.RecyclerView.OnScrollListener;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.SparseBooleanArray;
 import android.view.View;
 
 import com.android.documentsui.dirlist.MultiSelectManager.GridModel;
 
+@SmallTest
 public class MultiSelectManager_GridModelTest extends AndroidTestCase {
 
     private static final int VIEW_PADDING_PX = 5;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SelectionTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SelectionTest.java
index 64da750..72fc108 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SelectionTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SelectionTest.java
@@ -17,10 +17,11 @@
 package com.android.documentsui.dirlist;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 
-
+@SmallTest
 public class MultiSelectManager_SelectionTest extends AndroidTestCase{
 
     private Selection selection;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java
new file mode 100644
index 0000000..b4324a8
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java
@@ -0,0 +1,108 @@
+/*
+ * 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.dirlist;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.view.View;
+
+import com.android.documentsui.dirlist.MultiSelectManager.SelectionEnvironment;
+
+public class TestSelectionEnvironment implements SelectionEnvironment {
+
+    @Override
+    public void showBand(Rect rect) {
+    }
+
+    @Override
+    public void hideBand() {
+    }
+
+    @Override
+    public void addOnScrollListener(OnScrollListener listener) {
+    }
+
+    @Override
+    public void removeOnScrollListener(OnScrollListener listener) {
+    }
+
+    @Override
+    public void scrollBy(int dy) {
+    }
+
+    @Override
+    public int getHeight() {
+        return 0;
+    }
+
+    @Override
+    public void invalidateView() {
+    }
+
+    @Override
+    public void runAtNextFrame(Runnable r) {
+    }
+
+    @Override
+    public void removeCallback(Runnable r) {
+    }
+
+    @Override
+    public Point createAbsolutePoint(Point relativePoint) {
+        return null;
+    }
+
+    @Override
+    public Rect getAbsoluteRectForChildViewAt(int index) {
+        return null;
+    }
+
+    @Override
+    public int getAdapterPositionAt(int index) {
+        return 0;
+    }
+
+    @Override
+    public int getAdapterPositionForChildView(View view) {
+        return 0;
+    }
+
+    @Override
+    public int getColumnCount() {
+        return 0;
+    }
+
+    @Override
+    public int getRowCount() {
+        return 0;
+    }
+
+    @Override
+    public int getChildCount() {
+        return 0;
+    }
+
+    @Override
+    public int getVisibleChildCount() {
+        return 0;
+    }
+
+    @Override
+    public void focusItem(int position) {
+    }
+}
diff --git a/packages/FakeOemFeatures/AndroidManifest.xml b/packages/FakeOemFeatures/AndroidManifest.xml
index 93b8b47..fe74ad8 100644
--- a/packages/FakeOemFeatures/AndroidManifest.xml
+++ b/packages/FakeOemFeatures/AndroidManifest.xml
@@ -11,7 +11,9 @@
         android:allowClearUserData="false"
         android:allowBackup="false"
         android:hardwareAccelerated="true"
-        android:label="Fake OEM Features">
+        android:label="Fake OEM Features"
+        android:forceDeviceEncrypted="true"
+        android:encryptionAware="true">
 
         <service android:name=".FakeCoreService" android:process=":core"
                 android:label="Fake OEM Core Service" />
diff --git a/packages/FusedLocation/AndroidManifest.xml b/packages/FusedLocation/AndroidManifest.xml
index 6a4d4bf..ed84c0d 100644
--- a/packages/FusedLocation/AndroidManifest.xml
+++ b/packages/FusedLocation/AndroidManifest.xml
@@ -28,7 +28,9 @@
 
     <application
             android:label="@string/app_label"
-            android:process="system">
+            android:process="system"
+            android:forceDeviceEncrypted="true"
+            android:encryptionAware="true">
 
         <uses-library android:name="com.android.location.provider" />
 
@@ -37,7 +39,7 @@
              version. -->
         <service android:name="com.android.location.fused.FusedLocationService"
                  android:exported="true"
-                 android:permission="android.permission.WRITE_SECURE_SETTINGS" >
+                 android:permission="android.permission.WRITE_SECURE_SETTINGS">
            <intent-filter>
                <action android:name="com.android.location.service.FusedLocationProvider" />
            </intent-filter>
diff --git a/packages/InputDevices/AndroidManifest.xml b/packages/InputDevices/AndroidManifest.xml
index f0e4abc..07885ea 100644
--- a/packages/InputDevices/AndroidManifest.xml
+++ b/packages/InputDevices/AndroidManifest.xml
@@ -6,7 +6,9 @@
     <application
             android:allowClearUserData="false"
             android:label="@string/app_label"
-            android:process="system">
+            android:process="system"
+            android:forceDeviceEncrypted="true"
+            android:encryptionAware="true">
 
         <receiver android:name=".InputDeviceReceiver"
                 android:label="@string/keyboard_layouts_label">
diff --git a/packages/Keyguard/AndroidManifest.xml b/packages/Keyguard/AndroidManifest.xml
index e19246c..54972b4 100644
--- a/packages/Keyguard/AndroidManifest.xml
+++ b/packages/Keyguard/AndroidManifest.xml
@@ -45,7 +45,9 @@
     <application android:label="@string/app_name"
         android:process="com.android.systemui"
         android:persistent="true"
-        android:supportsRtl="true">
+        android:supportsRtl="true"
+        android:forceDeviceEncrypted="true"
+        android:encryptionAware="true">
 
     </application>
 </manifest>
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
index cea4319..3230beb 100644
--- a/packages/Keyguard/res/values-ja/strings.xml
+++ b/packages/Keyguard/res/values-ja/strings.xml
@@ -110,8 +110,8 @@
     <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_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>
diff --git a/packages/Keyguard/res/values-uz-rUZ/strings.xml b/packages/Keyguard/res/values-uz-rUZ/strings.xml
index b87298d..eae5ff8 100644
--- a/packages/Keyguard/res/values-uz-rUZ/strings.xml
+++ b/packages/Keyguard/res/values-uz-rUZ/strings.xml
@@ -22,9 +22,9 @@
     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-kodni kiriting"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM-karta PUK kodi va yangi PIN kodni tering"</string>
-    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM-karta PUK kodi"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Yangi SIM-karta PIN kodi"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"SIM karta PUK kodi va yangi PIN kodni tering"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM karta PUK kodi"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Yangi SIM karta PIN kodi"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Parolni kiritish uchun bosing"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Qulfni ochish uchun parolni kiriting"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Qulfni ochish uchun PIN-kodni kiriting"</string>
@@ -36,24 +36,24 @@
     <string name="keyguard_low_battery" msgid="8143808018719173859">"Zaryadlagichni ulang."</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Qulfni ochish uchun \"Menyu\"ga bosing."</string>
     <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Tarmoq qulflangan"</string>
-    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM-karta yo‘q"</string>
-    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Ushbu planshetda SIM-karta yo‘q."</string>
-    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Ushbu telefonda SIM-karta yo‘q."</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM karta yo‘q"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Ushbu planshetda SIM karta yo‘q."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Ushbu telefonda SIM karta yo‘q."</string>
     <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Telefonga SIM kartani joylashtiring."</string>
-    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-karta qo‘yilmagan yoki o‘qib bo‘lmayapti. SIM-kartani joylashtiring."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM karta qo‘yilmagan yoki o‘qib bo‘lmayapti. SIM kartani joylashtiring."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM kartadan foydalanib bo‘lmaydi."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM-kartangiz butunlay o‘chirilgan.\n Boshqa SIM-karta olish uchun aloqa operatori bilan bog‘laning."</string>
-    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-karta qulflangan."</string>
-    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-karta PUK kod bilan qulflangan."</string>
-    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM-karta qulfi ochilmoqda…"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM kartangiz butunlay o‘chirilgan.\n Boshqa SIM karta olish uchun aloqa operatori bilan bog‘laning."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM karta qulflangan."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM karta PUK kod bilan qulflangan."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM karta qulfi ochilmoqda…"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Chizmali qulfni ochish."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin qulfini ochish."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Parolli qulfni ochish."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Chizmali qulf maydoni."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Maydonni silang"</string>
     <string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"PIN-kod maydoni"</string>
-    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM-karta PIN kodi maydoni"</string>
-    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM-karta PUK kodi maydoni"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM karta PIN kodi maydoni"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM karta PUK kodi maydoni"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="7269583073750518672">"Uyg‘otkich signali <xliff:g id="ALARM">%1$s</xliff:g> da chalinadi."</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"O‘chirish"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Kiritish"</string>
@@ -67,11 +67,11 @@
     <string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"“<xliff:g id="CARRIER">%1$s</xliff:g>” SIM kartasi uchun PIN kodni kiriting"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN kodni tering"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"Parol kiriting"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. To‘liqroq ma’lumot olish uchun tarmoq operatori bilan bog‘laning."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta hozir o‘chirilgan. Davom etish uchun PUK kodni kiriting. To‘liqroq ma’lumot olish uchun tarmoq operatori bilan bog‘laning."</string>
     <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"“<xliff:g id="CARRIER">%1$s</xliff:g>” SIM kartasi o‘chirib qo‘yildi. Davom etish uchun PUK kodni kiriting. Tafsilotlar uchun aloqa operatoringizga murojaat qiling."</string>
     <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"So‘ralgan PIN kodni kiriting"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"So‘ralgan PIN kodni tasdiqlang"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-karta qulfi ochilmoqda…"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM karta qulfi ochilmoqda…"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 tadan 8 ta raqamgacha bo‘lgan PIN kodni kiriting."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kod kamida 8 ta raqam bo‘lishi shart."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"To‘g‘ri PUK kodni qayta kiriting. Qayta-qayta urinishlar SIM kartani butunlay o‘chirib qo‘yadi."</string>
@@ -94,18 +94,18 @@
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta noto‘g‘ri urinish qildingiz. Endi, ishchi profil o‘chirib tashlanadi va undagi barcha ma’lumotlar ham o‘chib ketadi."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz chizmali kalitni  <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri kiritdingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, planshet qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz chizmali kalitni <xliff:g id="NUMBER_0">%d</xliff:g> marta noto‘g‘ri chizdingiz. <xliff:g id="NUMBER_1">%d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, telefon qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
-    <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM-karta PIN kodi noto‘g‘ri. Qurilma qulfini ochish uchun aloqa operatoringiz bilan bog‘laning."</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM karta PIN kodi noto‘g‘ri. Qurilma qulfini ochish uchun aloqa operatoringiz bilan bog‘laning."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
       <item quantity="other">SIM kartaning PIN kodi noto‘g‘ri. Sizda yana <xliff:g id="NUMBER_1">%d</xliff:g> ta urinish qoldi.</item>
       <item quantity="one">SIM kartaning PIN kodi noto‘g‘ri. Qurilmani qulfdan chiqarish uchun sizda yana <xliff:g id="NUMBER_0">%d</xliff:g> ta urinish qoldi.</item>
     </plurals>
     <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM kartadan foydalanib bo‘lmaydi. Aloqa operatoringiz bilan bog‘laning."</string>
     <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="7576227366999858780">
-      <item quantity="other">SIM-kartaning PUK kodi noto‘g‘ri kiritildi. Yana <xliff:g id="NUMBER_1">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM-karta butunlay ishdan chiqadi.</item>
-      <item quantity="one">SIM-kartaning PUK kodi noto‘g‘ri kiritildi. Yana <xliff:g id="NUMBER_0">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM-karta butunlay ishdan chiqadi.</item>
+      <item quantity="other">SIM kartaning PUK kodi noto‘g‘ri kiritildi. Yana <xliff:g id="NUMBER_1">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM karta butunlay ishdan chiqadi.</item>
+      <item quantity="one">SIM kartaning PUK kodi noto‘g‘ri kiritildi. Yana <xliff:g id="NUMBER_0">%d</xliff:g> ta muvaffaqiyatsiz urinishdan so‘ng SIM karta butunlay ishdan chiqadi.</item>
     </plurals>
-    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM-karta PIN jarayoni amalga oshmadi!"</string>
-    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM-karta PUK jarayoni amalga oshmadi!"</string>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM karta PIN jarayoni amalga oshmadi!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM karta PUK jarayoni amalga oshmadi!"</string>
     <string name="kg_pin_accepted" msgid="1448241673570020097">"Kod qabul qilindi!"</string>
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Aloqa yo‘q."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Kiritish uslubi tugmasini almashtirish."</string>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index 5b1e45d..c7b217c 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -92,8 +92,8 @@
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统将移除此工作资料,这会删除所有的工作资料数据。"</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁平板电脑。系统将移除此工作资料,这会删除所有的工作资料数据。"</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"您已经 <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">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%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>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index f95b0ae..9d1df26 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManager;
 import android.app.AlarmManager;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -198,12 +197,18 @@
     }
 
     private String getOwnerInfo() {
-        ContentResolver res = getContext().getContentResolver();
         String info = null;
-        final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
-                KeyguardUpdateMonitor.getCurrentUser());
-        if (ownerInfoEnabled) {
-            info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
+        if (mLockPatternUtils.isDeviceOwnerInfoEnabled()) {
+            // Use the device owner information set by device policy client via
+            // device policy manager.
+            info = mLockPatternUtils.getDeviceOwnerInfo();
+        } else {
+            // Use the current user owner information if enabled.
+            final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
+                    KeyguardUpdateMonitor.getCurrentUser());
+            if (ownerInfoEnabled) {
+                info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
+            }
         }
         return info;
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 57ee319..3d78028 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -603,6 +603,7 @@
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
 
+        @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
             if (DEBUG) Log.d(TAG, "received broadcast " + action);
@@ -656,6 +657,7 @@
 
     private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
 
+        @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
             if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
@@ -788,6 +790,7 @@
             return new SimData(state, slotId, subId);
         }
 
+        @Override
         public String toString() {
             return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
         }
@@ -1693,5 +1696,19 @@
         for (int subId : mServiceStates.keySet()) {
             pw.println("    " + subId + "=" + mServiceStates.get(subId));
         }
+        if (mFpm != null && mFpm.isHardwareDetected()) {
+            final int userId = ActivityManager.getCurrentUser();
+            final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
+            pw.println("  Fingerprint state (user=" + userId + ")");
+            pw.println("    allowed=" + isUnlockingWithFingerprintAllowed());
+            pw.println("    auth'd=" + mUserFingerprintAuthenticated.get(userId));
+            pw.println("    authSinceBoot="
+                    + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
+            pw.println("    disabled(DPM)=" + isFingerprintDisabled(userId));
+            pw.println("    possible=" + isUnlockWithFingerprintPossible(userId));
+            pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
+            pw.println("    timedout=" + hasFingerprintUnlockTimedOut(userId));
+            pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
+        }
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index 0d4265a..1c96906 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -18,7 +18,7 @@
 
 import android.content.ContentResolver;
 import android.database.Cursor;
-import android.database.MatrixCursor;
+import android.database.sqlite.SQLiteException;
 import android.mtp.MtpObjectInfo;
 import android.net.Uri;
 import android.os.Bundle;
@@ -26,6 +26,7 @@
 import android.provider.DocumentsContract;
 import android.util.Log;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Date;
@@ -44,12 +45,14 @@
 
     private final MtpManager mMtpManager;
     private final ContentResolver mResolver;
+    private final MtpDatabase mDatabase;
     private final TaskList mTaskList = new TaskList();
     private boolean mHasBackgroundThread = false;
 
-    DocumentLoader(MtpManager mtpManager, ContentResolver resolver) {
+    DocumentLoader(MtpManager mtpManager, ContentResolver resolver, MtpDatabase database) {
         mMtpManager = mtpManager;
         mResolver = resolver;
+        mDatabase = database;
     }
 
     private static MtpObjectInfo[] loadDocuments(MtpManager manager, int deviceId, int[] handles)
@@ -65,13 +68,17 @@
             throws IOException {
         LoaderTask task = mTaskList.findTask(parent);
         if (task == null) {
+            if (parent.mDocumentId == null) {
+                throw new FileNotFoundException("Parent not found.");
+            }
+
             int parentHandle = parent.mObjectHandle;
             // Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to
             // getObjectHandles if we would like to obtain children under the root.
             if (parentHandle == CursorHelper.DUMMY_HANDLE_FOR_ROOT) {
                 parentHandle = MtpManager.OBJECT_HANDLE_ROOT_CHILDREN;
             }
-            task = new LoaderTask(parent, mMtpManager.getObjectHandles(
+            task = new LoaderTask(mDatabase, parent, mMtpManager.getObjectHandles(
                     parent.mDeviceId, parent.mStorageId, parentHandle));
             task.fillDocuments(loadDocuments(
                     mMtpManager,
@@ -83,11 +90,10 @@
         }
 
         mTaskList.addFirst(task);
-        if (!task.completed() && !mHasBackgroundThread) {
+        if (task.getState() == LoaderTask.STATE_LOADING && !mHasBackgroundThread) {
             mHasBackgroundThread = true;
             new BackgroundLoaderThread().start();
         }
-
         return task.createCursor(mResolver, columnNames);
     }
 
@@ -120,26 +126,20 @@
                     deviceId = task.mIdentifier.mDeviceId;
                     handles = task.getUnloadedObjectHandles(NUM_LOADING_ENTRIES);
                 }
-                MtpObjectInfo[] objectInfos;
+
                 try {
-                    objectInfos = loadDocuments(mMtpManager, deviceId, handles);
-                } catch (IOException exception) {
-                    objectInfos = null;
-                    Log.d(MtpDocumentsProvider.TAG, exception.getMessage());
-                }
-                synchronized (DocumentLoader.this) {
-                    if (objectInfos != null) {
-                        task.fillDocuments(objectInfos);
-                        final boolean shouldNotify =
-                                task.mLastNotified.getTime() <
-                                new Date().getTime() - NOTIFY_PERIOD_MS ||
-                                task.completed();
-                        if (shouldNotify) {
-                            task.notify(mResolver);
-                        }
-                    } else {
-                        mTaskList.remove(task);
+                    final MtpObjectInfo[] objectInfos =
+                            loadDocuments(mMtpManager, deviceId, handles);
+                    task.fillDocuments(objectInfos);
+                    final boolean shouldNotify =
+                            task.mLastNotified.getTime() <
+                            new Date().getTime() - NOTIFY_PERIOD_MS ||
+                            task.getState() != LoaderTask.STATE_LOADING;
+                    if (shouldNotify) {
+                        task.notify(mResolver);
                     }
+                } catch (IOException exception) {
+                    task.setError(exception);
                 }
             }
         }
@@ -156,7 +156,7 @@
 
         LoaderTask findRunningTask() {
             for (int i = 0; i < size(); i++) {
-                if (!get(i).completed())
+                if (get(i).getState() == LoaderTask.STATE_LOADING)
                     return get(i);
             }
             return null;
@@ -165,7 +165,7 @@
         void clearCompletedTasks() {
             int i = 0;
             while (i < size()) {
-                if (get(i).completed()) {
+                if (get(i).getState() == LoaderTask.STATE_COMPLETED) {
                     remove(i);
                 } else {
                     i++;
@@ -186,36 +186,51 @@
     }
 
     private static class LoaderTask {
+        static final int STATE_LOADING = 0;
+        static final int STATE_COMPLETED = 1;
+        static final int STATE_ERROR = 2;
+
+        final MtpDatabase mDatabase;
         final Identifier mIdentifier;
         final int[] mObjectHandles;
-        final MtpObjectInfo[] mObjectInfos;
         Date mLastNotified;
         int mNumLoaded;
+        Exception mError;
 
-        LoaderTask(Identifier identifier, int[] objectHandles) {
+        LoaderTask(MtpDatabase database, Identifier identifier, int[] objectHandles) {
+            mDatabase = database;
             mIdentifier = identifier;
             mObjectHandles = objectHandles;
-            mObjectInfos = new MtpObjectInfo[mObjectHandles.length];
             mNumLoaded = 0;
             mLastNotified = new Date();
         }
 
-        Cursor createCursor(ContentResolver resolver, String[] columnNames) {
-            final MatrixCursor cursor = new MatrixCursor(columnNames);
-            final Identifier rootIdentifier = new Identifier(
-                    mIdentifier.mDeviceId, mIdentifier.mStorageId);
-            for (int i = 0; i < mNumLoaded; i++) {
-                CursorHelper.addToCursor(mObjectInfos[i], rootIdentifier, cursor.newRow());
-            }
+        Cursor createCursor(ContentResolver resolver, String[] columnNames) throws IOException {
             final Bundle extras = new Bundle();
-            extras.putBoolean(DocumentsContract.EXTRA_LOADING, !completed());
+            switch (getState()) {
+                case STATE_LOADING:
+                    extras.putBoolean(DocumentsContract.EXTRA_LOADING, true);
+                    break;
+                case STATE_ERROR:
+                    throw new IOException(mError);
+            }
+
+            final Cursor cursor = mDatabase.queryChildDocuments(
+                    columnNames, mIdentifier.mDocumentId, /* use old ID format */ true);
             cursor.setNotificationUri(resolver, createUri());
             cursor.respond(extras);
+
             return cursor;
         }
 
-        boolean completed() {
-            return mNumLoaded == mObjectInfos.length;
+        int getState() {
+            if (mError != null) {
+                return STATE_ERROR;
+            } else if (mNumLoaded == mObjectHandles.length) {
+                return STATE_COMPLETED;
+            } else {
+                return STATE_LOADING;
+            }
         }
 
         int[] getUnloadedObjectHandles(int count) {
@@ -230,9 +245,32 @@
             mLastNotified = new Date();
         }
 
-        void fillDocuments(MtpObjectInfo[] objectInfos) {
-            for (int i = 0; i < objectInfos.length; i++) {
-                mObjectInfos[mNumLoaded++] = objectInfos[i];
+        void fillDocuments(MtpObjectInfo[] objectInfoList) {
+            if (objectInfoList.length == 0 || getState() != STATE_LOADING) {
+                return;
+            }
+            if (mNumLoaded == 0) {
+                mDatabase.startAddingChildDocuments(mIdentifier.mDocumentId);
+            }
+            try {
+                mDatabase.putChildDocuments(
+                        mIdentifier.mDeviceId, mIdentifier.mDocumentId, objectInfoList);
+                mNumLoaded += objectInfoList.length;
+            } catch (SQLiteException exp) {
+                mError = exp;
+                mNumLoaded = 0;
+            }
+            if (getState() != STATE_LOADING) {
+                mDatabase.stopAddingChildDocuments(mIdentifier.mDocumentId);
+            }
+        }
+
+        void setError(Exception message) {
+            final int lastState = getState();
+            mError = message;
+            mNumLoaded = 0;
+            if (lastState == STATE_LOADING) {
+                mDatabase.stopAddingChildDocuments(mIdentifier.mDocumentId);
             }
         }
 
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
index ae29f52..4238721e 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Identifier.java
@@ -23,6 +23,7 @@
     final int mDeviceId;
     final int mStorageId;
     final int mObjectHandle;
+    final String mDocumentId;
 
     static Identifier createFromRootId(String rootId) {
         final String[] components = rootId.split("_");
@@ -45,9 +46,14 @@
     }
 
     Identifier(int deviceId, int storageId, int objectHandle) {
+        this(deviceId, storageId, objectHandle, null);
+    }
+
+    Identifier(int deviceId, int storageId, int objectHandle, String documentId) {
         mDeviceId = deviceId;
         mStorageId = storageId;
         mObjectHandle = objectHandle;
+        mDocumentId = documentId;
     }
 
     // TODO: Make the ID persistent.
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
index 8568da0..3dc69cc 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
@@ -16,20 +16,21 @@
 
 package com.android.mtp;
 
+import static com.android.mtp.MtpDatabaseConstants.*;
+
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.res.Resources;
 import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
 import android.mtp.MtpObjectInfo;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.util.Objects;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Database for MTP objects.
@@ -44,300 +45,288 @@
  * remembers the map of document ID and object handle, and remaps new object handle with document ID
  * by comparing the directory structure and object name.
  *
+ * To start putting documents into the database, the client needs to call
+ * {@link #startAddingChildDocuments(String)} with the parent document ID. Also it needs to call
+ * {@link #stopAddingChildDocuments(String)} after putting all child documents to the database.
+ * (All explanations are same for root documents)
+ *
+ * database.startAddingChildDocuments();
+ * database.putChildDocuments();
+ * database.stopAddingChildDocuments();
+ *
+ * To update the existing documents, the client code can repeat to call the three methods again.
+ * The newly added rows update corresponding existing rows that have same MTP identifier like
+ * objectHandle.
+ *
+ * The client can call putChildDocuments multiple times to add documents by chunk, but it needs to
+ * put all documents under the parent before calling stopAddingChildDocuments. Otherwise missing
+ * documents are regarded as deleted, and will be removed from the database.
+ *
+ * If the client calls clearMtpIdentifier(), it clears MTP identifier in the database. In this case,
+ * the database tries to find corresponding rows by using document's name instead of MTP identifier
+ * at the next update cycle.
+ *
  * TODO: Remove @VisibleForTesting annotation when we start to use this class.
  * TODO: Improve performance by SQL optimization.
  */
 @VisibleForTesting
 class MtpDatabase {
-    private static final int VERSION = 1;
-    private static final String NAME = "mtp";
-
-    private static final String TABLE_DOCUMENTS = "Documents";
-
-    static final String COLUMN_DEVICE_ID = "device_id";
-    static final String COLUMN_STORAGE_ID = "storage_id";
-    static final String COLUMN_OBJECT_HANDLE = "object_handle";
-    static final String COLUMN_PARENT_DOCUMENT_ID = "parent_document_id";
-    static final String COLUMN_ROW_STATE = "row_state";
+    private final MtpDatabaseInternal mDatabase;
 
     /**
-     * The state represents that the row has a valid object handle.
+     * Mapping mode for roots/documents where we start adding child documents.
+     * Methods operate the state needs to be synchronized.
      */
-    static final int ROW_STATE_MAPPED = 0;
-
-    /**
-     * The state represents that the object handle was cleared because the MTP session closed.
-     * External application can still fetch the unmapped documents. If the external application
-     * tries to open an unmapped document, the provider resolves the document with new object handle
-     * ahead.
-     */
-    static final int ROW_STATE_UNMAPPED = 1;
-
-    /**
-     * The state represents the raw has a valid object handle but it may be going to be merged into
-     * another unmapped row. After fetching all documents under the parent, the database tries to
-     * map the mapping document and the unmapped document in order to keep old document ID alive.
-     */
-    static final int ROW_STATE_MAPPING = 2;
-
-    private static final String SELECTION_DOCUMENT_ID =
-            DocumentsContract.Document.COLUMN_DOCUMENT_ID + " = ?";
-    private static final String SELECTION_ROOT_DOCUMENTS =
-            COLUMN_DEVICE_ID + " = ? AND " + COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
-    private static final String SELECTION_CHILD_DOCUMENTS = COLUMN_PARENT_DOCUMENT_ID + " = ?";
-
-    static class ParentNotFoundException extends Exception {}
-
-    private static class OpenHelper extends SQLiteOpenHelper {
-        private static final String QUERY_CREATE_DOCUMENTS =
-                "CREATE TABLE " + TABLE_DOCUMENTS + " (" +
-                DocumentsContract.Document.COLUMN_DOCUMENT_ID +
-                    " INTEGER PRIMARY KEY AUTOINCREMENT," +
-                COLUMN_DEVICE_ID + " INTEGER NOT NULL," +
-                COLUMN_STORAGE_ID + " INTEGER," +
-                COLUMN_OBJECT_HANDLE + " INTEGER," +
-                COLUMN_PARENT_DOCUMENT_ID + " INTEGER," +
-                COLUMN_ROW_STATE + " INTEGER NOT NULL," +
-                DocumentsContract.Document.COLUMN_MIME_TYPE + " TEXT," +
-                DocumentsContract.Document.COLUMN_DISPLAY_NAME + " TEXT NOT NULL," +
-                DocumentsContract.Document.COLUMN_SUMMARY + " TEXT," +
-                DocumentsContract.Document.COLUMN_LAST_MODIFIED + " INTEGER," +
-                DocumentsContract.Document.COLUMN_ICON + " INTEGER," +
-                DocumentsContract.Document.COLUMN_FLAGS + " INTEGER NOT NULL," +
-                DocumentsContract.Document.COLUMN_SIZE + " INTEGER NOT NULL);";
-
-        public OpenHelper(Context context) {
-            super(context, NAME, null, VERSION);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL(QUERY_CREATE_DOCUMENTS);
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    private final SQLiteDatabase database;
+    private final Map<String, Integer> mMappingMode = new HashMap<>();
 
     @VisibleForTesting
-    MtpDatabase(Context context) {
-        final OpenHelper helper = new OpenHelper(context);
-        database = helper.getWritableDatabase();
+    MtpDatabase(Context context, int flags) {
+        mDatabase = new MtpDatabaseInternal(context, flags);
     }
 
+    /**
+     * Closes the database.
+     */
     @VisibleForTesting
-    static void deleteDatabase(Context context) {
-        SQLiteDatabase.deleteDatabase(context.getDatabasePath(NAME));
+    void close() {
+        mDatabase.close();
     }
 
+    /**
+     * {@link MtpDatabaseInternal#queryRoots}
+     */
+    Cursor queryRoots(String[] columnNames) {
+        return mDatabase.queryRoots(columnNames);
+    }
+
+    /**
+     * {@link MtpDatabaseInternal#queryRootDocuments}
+     */
     @VisibleForTesting
     Cursor queryRootDocuments(String[] columnNames) {
-        return database.query(
-                TABLE_DOCUMENTS,
-                columnNames,
-                COLUMN_ROW_STATE + " IN (?, ?)",
-                strings(ROW_STATE_MAPPED, ROW_STATE_UNMAPPED),
-                null,
-                null,
-                null);
+        return mDatabase.queryRootDocuments(columnNames);
     }
 
+    /**
+     * {@link MtpDatabaseInternal#queryChildDocuments}
+     */
     @VisibleForTesting
     Cursor queryChildDocuments(String[] columnNames, String parentDocumentId) {
-        return database.query(
-                TABLE_DOCUMENTS,
-                columnNames,
-                COLUMN_ROW_STATE + " IN (?, ?) AND " + COLUMN_PARENT_DOCUMENT_ID + " = ?",
-                strings(ROW_STATE_MAPPED, ROW_STATE_UNMAPPED, parentDocumentId),
-                null,
-                null,
-                null);
+        return queryChildDocuments(columnNames, parentDocumentId, false);
     }
 
     @VisibleForTesting
-    void putRootDocuments(int deviceId, Resources resources, MtpRoot[] roots) {
-        final ContentValues[] valuesList = new ContentValues[roots.length];
-        for (int i = 0; i < roots.length; i++) {
-            if (roots[i].mDeviceId != deviceId) {
-                throw new IllegalArgumentException();
+    Cursor queryChildDocuments(String[] columnNames, String parentDocumentId, boolean useOldId) {
+        final String[] newColumnNames = new String[columnNames.length];
+
+        // TODO: Temporary replace document ID with old format.
+        for (int i = 0; i < columnNames.length; i++) {
+            if (useOldId && DocumentsContract.Document.COLUMN_DOCUMENT_ID.equals(columnNames[i])) {
+                newColumnNames[i] = COLUMN_DEVICE_ID + " || '_' || " + COLUMN_STORAGE_ID +
+                        " || '_' || IFNULL(" + COLUMN_OBJECT_HANDLE + ",0) AS " +
+                        DocumentsContract.Document.COLUMN_DOCUMENT_ID;
+            } else {
+                newColumnNames[i] = columnNames[i];
             }
-            valuesList[i] = new ContentValues();
-            getRootDocumentValues(valuesList[i], resources, roots[i]);
         }
-        putDocuments(valuesList, SELECTION_ROOT_DOCUMENTS, Integer.toString(deviceId));
+
+        return mDatabase.queryChildDocuments(newColumnNames, parentDocumentId);
     }
 
+    Identifier createIdentifier(String parentDocumentId) {
+        return mDatabase.createIdentifier(parentDocumentId);
+    }
+
+    /**
+     * {@link MtpDatabaseInternal#removeDeviceRows}
+     */
+    void removeDeviceRows(int deviceId) {
+        mDatabase.removeDeviceRows(deviceId);
+    }
+
+    /**
+     * Invokes {@link MtpDatabaseInternal#startAddingDocuments} for root documents.
+     * @param deviceId Device ID.
+     */
+    synchronized void startAddingRootDocuments(int deviceId) {
+        final String mappingStateKey = getRootDocumentsMappingStateKey(deviceId);
+        if (mMappingMode.containsKey(mappingStateKey)) {
+            throw new Error("Mapping for the root has already started.");
+        }
+        mMappingMode.put(
+                mappingStateKey,
+                mDatabase.startAddingDocuments(
+                        SELECTION_ROOT_DOCUMENTS, Integer.toString(deviceId)));
+    }
+
+    /**
+     * Invokes {@link MtpDatabaseInternal#startAddingDocuments} for child of specific documents.
+     * @param parentDocumentId Document ID for parent document.
+     */
     @VisibleForTesting
-    void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) {
+    synchronized void startAddingChildDocuments(String parentDocumentId) {
+        final String mappingStateKey = getChildDocumentsMappingStateKey(parentDocumentId);
+        if (mMappingMode.containsKey(mappingStateKey)) {
+            throw new Error("Mapping for the root has already started.");
+        }
+        mMappingMode.put(
+                mappingStateKey,
+                mDatabase.startAddingDocuments(SELECTION_CHILD_DOCUMENTS, parentDocumentId));
+    }
+
+    /**
+     * Puts root information to database.
+     * @param deviceId Device ID
+     * @param resources Resources required to localize root name.
+     * @param roots List of root information.
+     * @return If roots are added or removed from the database.
+     */
+    synchronized boolean putRootDocuments(int deviceId, Resources resources, MtpRoot[] roots) {
+        mDatabase.beginTransaction();
+        try {
+            final boolean heuristic;
+            final String mapColumn;
+            switch (mMappingMode.get(getRootDocumentsMappingStateKey(deviceId))) {
+                case MAP_BY_MTP_IDENTIFIER:
+                    heuristic = false;
+                    mapColumn = COLUMN_STORAGE_ID;
+                    break;
+                case MAP_BY_NAME:
+                    heuristic = true;
+                    mapColumn = Document.COLUMN_DISPLAY_NAME;
+                    break;
+                default:
+                    throw new Error("Unexpected map mode.");
+            }
+            final ContentValues[] valuesList = new ContentValues[roots.length];
+            for (int i = 0; i < roots.length; i++) {
+                if (roots[i].mDeviceId != deviceId) {
+                    throw new IllegalArgumentException();
+                }
+                valuesList[i] = new ContentValues();
+                getRootDocumentValues(valuesList[i], resources, roots[i]);
+            }
+            final boolean changed = mDatabase.putDocuments(
+                    valuesList,
+                    SELECTION_ROOT_DOCUMENTS,
+                    Integer.toString(deviceId),
+                    heuristic,
+                    mapColumn);
+            final ContentValues values = new ContentValues();
+            int i = 0;
+            for (final MtpRoot root : roots) {
+                // Use the same value for the root ID and the corresponding document ID.
+                final String documentId = valuesList[i++].getAsString(Document.COLUMN_DOCUMENT_ID);
+                // If it fails to insert/update documents, the document ID will be set with -1.
+                // In this case we don't insert/update root extra information neither.
+                if (documentId == null) {
+                    continue;
+                }
+                values.put(Root.COLUMN_ROOT_ID, documentId);
+                values.put(
+                        Root.COLUMN_FLAGS,
+                        Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE);
+                values.put(Root.COLUMN_AVAILABLE_BYTES, root.mFreeSpace);
+                values.put(Root.COLUMN_CAPACITY_BYTES, root.mMaxCapacity);
+                values.put(Root.COLUMN_MIME_TYPES, "");
+                mDatabase.putRootExtra(values);
+            }
+            mDatabase.setTransactionSuccessful();
+            return changed;
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    /**
+     * Puts document information to database.
+     * @param deviceId Device ID
+     * @param parentId Parent document ID.
+     * @param documents List of document information.
+     */
+    @VisibleForTesting
+    synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) {
+        final boolean heuristic;
+        final String mapColumn;
+        switch (mMappingMode.get(getChildDocumentsMappingStateKey(parentId))) {
+            case MAP_BY_MTP_IDENTIFIER:
+                heuristic = false;
+                mapColumn = COLUMN_OBJECT_HANDLE;
+                break;
+            case MAP_BY_NAME:
+                heuristic = true;
+                mapColumn = Document.COLUMN_DISPLAY_NAME;
+                break;
+            default:
+                throw new Error("Unexpected map mode.");
+        }
         final ContentValues[] valuesList = new ContentValues[documents.length];
         for (int i = 0; i < documents.length; i++) {
             valuesList[i] = new ContentValues();
             getChildDocumentValues(valuesList[i], deviceId, parentId, documents[i]);
         }
-        putDocuments(valuesList, SELECTION_CHILD_DOCUMENTS, parentId);
+        mDatabase.putDocuments(
+                valuesList, SELECTION_CHILD_DOCUMENTS, parentId, heuristic, mapColumn);
     }
 
     /**
-     * Clears MTP related identifier.
-     * It clears MTP's object handle and storage ID that are not stable over MTP sessions and mark
-     * the all documents as 'unmapped'. It also remove 'mapping' rows as mapping is cancelled now.
+     * Clears mapping between MTP identifier and document/root ID.
      */
     @VisibleForTesting
-    void clearMapping() {
-        database.beginTransaction();
-        try {
-            database.delete(
-                    TABLE_DOCUMENTS, COLUMN_ROW_STATE + " = ?", strings(ROW_STATE_MAPPING));
-            final ContentValues values = new ContentValues();
-            values.putNull(COLUMN_OBJECT_HANDLE);
-            values.putNull(COLUMN_STORAGE_ID);
-            values.put(COLUMN_ROW_STATE, ROW_STATE_UNMAPPED);
-            database.update(TABLE_DOCUMENTS, values, null, null);
-            database.setTransactionSuccessful();
-        } finally {
-            database.endTransaction();
-        }
-    }
-
-    @VisibleForTesting
-    void resolveRootDocuments(int deviceId) {
-        resolveDocuments(SELECTION_ROOT_DOCUMENTS, Integer.toString(deviceId));
-    }
-
-    @VisibleForTesting
-    void resolveChildDocuments(String parentId) {
-        resolveDocuments(SELECTION_CHILD_DOCUMENTS, parentId);
+    synchronized void clearMapping() {
+        mDatabase.clearMapping();
+        mMappingMode.clear();
     }
 
     /**
-     * Puts the documents into the database.
-     * If the database found another unmapped document that shares the same name and parent,
-     * the document may be merged into the unmapped document. In that case, the database marks the
-     * root as 'mapping' and wait for {@link #resolveRootDocuments(int)} is invoked.
-     * @param valuesList Values that are stored in the database.
-     * @param selection SQL where closure to select rows that shares the same parent.
-     * @param arg Argument for selection SQL.
+     * Stops adding root documents.
+     * @param deviceId Device ID.
+     * @return True if new rows are added/removed.
      */
-    private void putDocuments(ContentValues[] valuesList, String selection, String arg) {
-        database.beginTransaction();
-        try {
-            for (final ContentValues values : valuesList) {
-                final String displayName =
-                        values.getAsString(DocumentsContract.Document.COLUMN_DISPLAY_NAME);
-                final long numUnmapped = DatabaseUtils.queryNumEntries(
-                        database,
-                        TABLE_DOCUMENTS,
-                        selection + " AND " +
-                        COLUMN_ROW_STATE + " = ? AND " +
-                        DocumentsContract.Document.COLUMN_DISPLAY_NAME + " = ?",
-                        strings(arg, ROW_STATE_UNMAPPED, displayName));
-                if (numUnmapped != 0) {
-                    values.put(COLUMN_ROW_STATE, ROW_STATE_MAPPING);
-                }
-                database.insert(TABLE_DOCUMENTS, null, values);
-            }
-
-            database.setTransactionSuccessful();
-        } finally {
-            database.endTransaction();
+    synchronized boolean stopAddingRootDocuments(int deviceId) {
+        final String mappingModeKey = getRootDocumentsMappingStateKey(deviceId);
+        switch (mMappingMode.get(mappingModeKey)) {
+            case MAP_BY_MTP_IDENTIFIER:
+                mMappingMode.remove(mappingModeKey);
+                return mDatabase.stopAddingDocuments(
+                        SELECTION_ROOT_DOCUMENTS,
+                        Integer.toString(deviceId),
+                        COLUMN_STORAGE_ID);
+            case MAP_BY_NAME:
+                mMappingMode.remove(mappingModeKey);
+                return mDatabase.stopAddingDocuments(
+                        SELECTION_ROOT_DOCUMENTS,
+                        Integer.toString(deviceId),
+                        Document.COLUMN_DISPLAY_NAME);
+            default:
+                throw new Error("Unexpected mapping state.");
         }
     }
 
     /**
-     * Maps 'unmapped' document and 'mapping' document that don't have document but shares the same
-     * name.
-     * If the database does not find corresponding 'mapping' document, it just removes 'unmapped'
-     * document from the database.
-     * @param selection Query to select rows for resolving.
-     * @param arg Argument for selection SQL.
+     * Stops adding documents under the parent.
+     * @param parentId Document ID of the parent.
      */
-    private void resolveDocuments(String selection, String arg) {
-        database.beginTransaction();
-        try {
-            // Get 1-to-1 mapping of unmapped document and mapping document.
-            final String unmappedIdQuery = createStateFilter(
-                    ROW_STATE_UNMAPPED, DocumentsContract.Document.COLUMN_DOCUMENT_ID);
-            final String mappingIdQuery = createStateFilter(
-                    ROW_STATE_MAPPING, DocumentsContract.Document.COLUMN_DOCUMENT_ID);
-            // SQL should be like:
-            // SELECT group_concat(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END),
-            //        group_concat(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END)
-            // WHERE device_id = ? AND parent_document_id IS NULL
-            // GROUP BY display_name
-            // HAVING count(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END) = 1 AND
-            //        count(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END) = 1
-            final Cursor mergingCursor = database.query(
-                    TABLE_DOCUMENTS,
-                    new String[] {
-                            "group_concat(" + unmappedIdQuery + ")",
-                            "group_concat(" + mappingIdQuery + ")"
-                    },
-                    selection,
-                    strings(arg),
-                    DocumentsContract.Document.COLUMN_DISPLAY_NAME,
-                    "count(" + unmappedIdQuery + ") = 1 AND count(" + mappingIdQuery + ") = 1",
-                    null);
-
-            final ContentValues values = new ContentValues();
-            while (mergingCursor.moveToNext()) {
-                final String unmappedId = mergingCursor.getString(0);
-                final String mappingId = mergingCursor.getString(1);
-
-                // Obtain the new values including the latest object handle from mapping row.
-                final Cursor mappingCursor = database.query(
-                        TABLE_DOCUMENTS,
-                        null,
-                        SELECTION_DOCUMENT_ID,
-                        new String[] { mappingId },
-                        null,
-                        null,
-                        null);
-                mappingCursor.moveToNext();
-                values.clear();
-                DatabaseUtils.cursorRowToContentValues(mappingCursor, values);
-                mappingCursor.close();
-                values.remove(DocumentsContract.Document.COLUMN_DOCUMENT_ID);
-
-                // Set the new values into unmapped documents and get it back to 'normal' state.
-                values.put(COLUMN_ROW_STATE, ROW_STATE_MAPPED);
-                database.update(
-                        TABLE_DOCUMENTS,
-                        values,
-                        SELECTION_DOCUMENT_ID,
-                        new String[] { unmappedId });
-
-                // Delete 'mapping' row.
-                database.delete(
-                        TABLE_DOCUMENTS,
-                        SELECTION_DOCUMENT_ID,
-                        new String[] { mappingId });
-            }
-            mergingCursor.close();
-
-            // Delete all unmapped rows that cannot be mapped.
-            database.delete(
-                    TABLE_DOCUMENTS,
-                    COLUMN_ROW_STATE + " = ? AND " + selection,
-                    strings(ROW_STATE_UNMAPPED, arg));
-
-            // The database cannot find old document ID for the mapping rows.
-            // Turn the all mapping rows into mapped state, which means the rows become to be
-            // valid with new document ID.
-            values.clear();
-            values.put(COLUMN_ROW_STATE, ROW_STATE_MAPPED);
-            database.update(
-                    TABLE_DOCUMENTS,
-                    values,
-                    COLUMN_ROW_STATE + " = ? AND " + selection,
-                    strings(ROW_STATE_MAPPING, arg));
-            database.setTransactionSuccessful();
-        } finally {
-            database.endTransaction();
+    @VisibleForTesting
+    synchronized void stopAddingChildDocuments(String parentId) {
+        final String mappingModeKey = getChildDocumentsMappingStateKey(parentId);
+        switch (mMappingMode.get(mappingModeKey)) {
+            case MAP_BY_MTP_IDENTIFIER:
+                mDatabase.stopAddingDocuments(
+                        SELECTION_CHILD_DOCUMENTS,
+                        parentId,
+                        COLUMN_OBJECT_HANDLE);
+                break;
+            case MAP_BY_NAME:
+                mDatabase.stopAddingDocuments(
+                        SELECTION_CHILD_DOCUMENTS,
+                        parentId,
+                        Document.COLUMN_DISPLAY_NAME);
+                break;
+            default:
+                throw new Error("Unexpected mapping state.");
         }
+        mMappingMode.remove(mappingModeKey);
     }
 
     /**
@@ -353,8 +342,8 @@
         values.put(COLUMN_STORAGE_ID, root.mStorageId);
         values.putNull(COLUMN_OBJECT_HANDLE);
         values.putNull(COLUMN_PARENT_DOCUMENT_ID);
-        values.put(COLUMN_ROW_STATE, ROW_STATE_MAPPED);
-        values.put(Document.COLUMN_MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR);
+        values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
+        values.put(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
         values.put(Document.COLUMN_DISPLAY_NAME, root.getRootName(resources));
         values.putNull(Document.COLUMN_SUMMARY);
         values.putNull(Document.COLUMN_LAST_MODIFIED);
@@ -377,20 +366,20 @@
         final String mimeType = CursorHelper.formatTypeToMimeType(info.getFormat());
         int flag = 0;
         if (info.getProtectionStatus() == 0) {
-            flag |= DocumentsContract.Document.FLAG_SUPPORTS_DELETE |
-                    DocumentsContract.Document.FLAG_SUPPORTS_WRITE;
-            if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
-                flag |= DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE;
+            flag |= Document.FLAG_SUPPORTS_DELETE |
+                    Document.FLAG_SUPPORTS_WRITE;
+            if (mimeType == Document.MIME_TYPE_DIR) {
+                flag |= Document.FLAG_DIR_SUPPORTS_CREATE;
             }
         }
         if (info.getThumbCompressedSize() > 0) {
-            flag |= DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL;
+            flag |= Document.FLAG_SUPPORTS_THUMBNAIL;
         }
         values.put(COLUMN_DEVICE_ID, deviceId);
         values.put(COLUMN_STORAGE_ID, info.getStorageId());
         values.put(COLUMN_OBJECT_HANDLE, info.getObjectHandle());
         values.put(COLUMN_PARENT_DOCUMENT_ID, parentId);
-        values.put(COLUMN_ROW_STATE, ROW_STATE_MAPPED);
+        values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
         values.put(Document.COLUMN_MIME_TYPE, mimeType);
         values.put(Document.COLUMN_DISPLAY_NAME, info.getName());
         values.putNull(Document.COLUMN_SUMMARY);
@@ -403,27 +392,18 @@
     }
 
     /**
-     * Converts values into string array.
-     * @param args Values converted into string array.
-     * @return String array.
+     * @param deviceId Device ID.
+     * @return Key for {@link #mMappingMode}.
      */
-    private static String[] strings(Object... args) {
-        final String[] results = new String[args.length];
-        for (int i = 0; i < args.length; i++) {
-            results[i] = Objects.toString(args[i]);
-        }
-        return results;
+    private static String getRootDocumentsMappingStateKey(int deviceId) {
+        return "RootDocuments/" + deviceId;
     }
 
     /**
-     * Gets SQL expression that represents the given value or NULL depends on the row state.
-     * @param state Expected row state.
-     * @param a SQL value.
-     * @return Expression that represents a if the row state is expected one, and represents NULL
-     *     otherwise.
+     * @param parentDocumentId Document ID for the parent document.
+     * @return Key for {@link #mMappingMode}.
      */
-    private static String createStateFilter(int state, String a) {
-        return "CASE WHEN " + COLUMN_ROW_STATE + " = " + Integer.toString(state) +
-                " THEN " + a + " ELSE NULL END";
+    private static String getChildDocumentsMappingStateKey(String parentDocumentId) {
+        return "ChildDocuments/" + parentDocumentId;
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
new file mode 100644
index 0000000..97c1d29
--- /dev/null
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mtp;
+
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+
+/**
+ * Class containing MtpDatabase constants.
+ */
+class MtpDatabaseConstants {
+    static final int DATABASE_VERSION = 1;
+    static final String DATABASE_NAME = null;
+
+    static final int FLAG_DATABASE_IN_MEMORY = 1;
+    static final int FLAG_DATABASE_IN_FILE = 0;
+
+    /**
+     * Table representing documents including root documents.
+     */
+    static final String TABLE_DOCUMENTS = "Documents";
+
+    /**
+     * Table containing additional information only available for root documents.
+     * The table uses same primary keys with corresponding documents.
+     */
+    static final String TABLE_ROOT_EXTRA = "RootExtra";
+
+    /**
+     * View to join Documents and RootExtra tables to provide roots information.
+     */
+    static final String VIEW_ROOTS = "Roots";
+
+    static final String COLUMN_DEVICE_ID = "device_id";
+    static final String COLUMN_STORAGE_ID = "storage_id";
+    static final String COLUMN_OBJECT_HANDLE = "object_handle";
+    static final String COLUMN_PARENT_DOCUMENT_ID = "parent_document_id";
+    static final String COLUMN_ROW_STATE = "row_state";
+
+    /**
+     * The state represents that the row has a valid object handle.
+     */
+    static final int ROW_STATE_VALID = 0;
+
+    /**
+     * The state represents that the rows added at the previous cycle and need to be updated with
+     * fresh values.
+     * The row may not have valid object handle. External application can still fetch the documents.
+     * If the external application tries to fetch object handle, the provider resolves pending
+     * documents with invalidated documents ahead.
+     */
+    static final int ROW_STATE_INVALIDATED = 1;
+
+    /**
+     * The state represents the raw has a valid object handle but it may be going to be mapped with
+     * another rows invalidated. After fetching all documents under the parent, the database tries
+     * to map the pending documents and the invalidated documents in order to keep old document ID
+     * alive.
+     */
+    static final int ROW_STATE_PENDING = 2;
+
+    /**
+     * Mapping mode that uses MTP identifier to find corresponding rows.
+     */
+    static final int MAP_BY_MTP_IDENTIFIER = 0;
+
+    /**
+     * Mapping mode that uses name to find corresponding rows.
+     */
+    static final int MAP_BY_NAME = 1;
+
+    static final String SELECTION_DOCUMENT_ID = Document.COLUMN_DOCUMENT_ID + " = ?";
+    static final String SELECTION_ROOT_ID = Root.COLUMN_ROOT_ID + " = ?";
+    static final String SELECTION_ROOT_DOCUMENTS =
+            COLUMN_DEVICE_ID + " = ? AND " + COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
+    static final String SELECTION_CHILD_DOCUMENTS = COLUMN_PARENT_DOCUMENT_ID + " = ?";
+
+    static final String QUERY_CREATE_DOCUMENTS =
+            "CREATE TABLE " + TABLE_DOCUMENTS + " (" +
+            Document.COLUMN_DOCUMENT_ID +
+                " INTEGER PRIMARY KEY AUTOINCREMENT," +
+            COLUMN_DEVICE_ID + " INTEGER NOT NULL," +
+            COLUMN_STORAGE_ID + " INTEGER," +
+            COLUMN_OBJECT_HANDLE + " INTEGER," +
+            COLUMN_PARENT_DOCUMENT_ID + " INTEGER," +
+            COLUMN_ROW_STATE + " INTEGER NOT NULL," +
+            Document.COLUMN_MIME_TYPE + " TEXT," +
+            Document.COLUMN_DISPLAY_NAME + " TEXT NOT NULL," +
+            Document.COLUMN_SUMMARY + " TEXT," +
+            Document.COLUMN_LAST_MODIFIED + " INTEGER," +
+            Document.COLUMN_ICON + " INTEGER," +
+            Document.COLUMN_FLAGS + " INTEGER NOT NULL," +
+            Document.COLUMN_SIZE + " INTEGER NOT NULL);";
+
+    static final String QUERY_CREATE_ROOT_EXTRA =
+            "CREATE TABLE " + TABLE_ROOT_EXTRA + " (" +
+            Root.COLUMN_ROOT_ID + " INTEGER PRIMARY KEY," +
+            Root.COLUMN_FLAGS + " INTEGER NOT NULL," +
+            Root.COLUMN_AVAILABLE_BYTES + " INTEGER NOT NULL," +
+            Root.COLUMN_CAPACITY_BYTES + " INTEGER NOT NULL," +
+            Root.COLUMN_MIME_TYPES + " TEXT NOT NULL);";
+
+    /**
+     * Creates a view to join Documents table and RootExtra table on their primary keys to
+     * provide DocumentContract.Root equivalent information.
+     */
+    static final String QUERY_CREATE_VIEW_ROOTS =
+            "CREATE VIEW " + VIEW_ROOTS + " AS SELECT " +
+                    TABLE_DOCUMENTS + "." + Document.COLUMN_DOCUMENT_ID + " AS " +
+                            Root.COLUMN_ROOT_ID + "," +
+                    TABLE_ROOT_EXTRA + "." + Root.COLUMN_FLAGS + "," +
+                    TABLE_DOCUMENTS + "." + Document.COLUMN_ICON + " AS " +
+                            Root.COLUMN_ICON + "," +
+                    TABLE_DOCUMENTS + "." + Document.COLUMN_DISPLAY_NAME + " AS " +
+                            Root.COLUMN_TITLE + "," +
+                    TABLE_DOCUMENTS + "." + Document.COLUMN_SUMMARY + " AS " +
+                            Root.COLUMN_SUMMARY + "," +
+                    // Temporary replace COLUMN_DOCUMENT_ID with old format.
+                    TABLE_DOCUMENTS + "." + Document.COLUMN_DOCUMENT_ID + " AS " +
+                    Root.COLUMN_DOCUMENT_ID + "_," +
+                    TABLE_DOCUMENTS + "." + COLUMN_DEVICE_ID + "|| '_' ||" +
+                    TABLE_DOCUMENTS + "." + COLUMN_STORAGE_ID + "||'_0' AS " +
+                    Root.COLUMN_DOCUMENT_ID + "," +
+                    TABLE_ROOT_EXTRA + "." + Root.COLUMN_AVAILABLE_BYTES + "," +
+                    TABLE_ROOT_EXTRA + "." + Root.COLUMN_CAPACITY_BYTES + "," +
+                    TABLE_ROOT_EXTRA + "." + Root.COLUMN_MIME_TYPES + "," +
+                    TABLE_DOCUMENTS + "." + COLUMN_ROW_STATE +
+            " FROM " + TABLE_DOCUMENTS + " INNER JOIN " + TABLE_ROOT_EXTRA +
+            " ON " +
+                    COLUMN_PARENT_DOCUMENT_ID + " IS NULL AND " +
+                    TABLE_DOCUMENTS + "." + Document.COLUMN_DOCUMENT_ID +
+                    "=" +
+                    TABLE_ROOT_EXTRA + "." + Root.COLUMN_ROOT_ID;
+}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseInternal.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseInternal.java
new file mode 100644
index 0000000..9c5d6b6
--- /dev/null
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseInternal.java
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mtp;
+
+import static com.android.mtp.MtpDatabaseConstants.*;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+
+import java.util.Objects;
+
+/**
+ * Class that provides operations processing SQLite database directly.
+ */
+class MtpDatabaseInternal {
+    private static class OpenHelper extends SQLiteOpenHelper {
+        public OpenHelper(Context context, int flags) {
+            super(context,
+                  flags == FLAG_DATABASE_IN_MEMORY ? null : DATABASE_NAME,
+                  null,
+                  DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL(QUERY_CREATE_DOCUMENTS);
+            db.execSQL(QUERY_CREATE_ROOT_EXTRA);
+            db.execSQL(QUERY_CREATE_VIEW_ROOTS);
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private final SQLiteDatabase mDatabase;
+
+    MtpDatabaseInternal(Context context, int flags) {
+        final OpenHelper helper = new OpenHelper(context, flags);
+        mDatabase = helper.getWritableDatabase();
+    }
+
+    void close() {
+        mDatabase.close();
+    }
+
+    /**
+     * Queries roots information.
+     * @param columnNames Column names defined in {@link android.provider.DocumentsContract.Root}.
+     * @return Database cursor.
+     */
+    Cursor queryRoots(String[] columnNames) {
+        return mDatabase.query(
+                VIEW_ROOTS,
+                columnNames,
+                COLUMN_ROW_STATE + " IN (?, ?)",
+                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED),
+                null,
+                null,
+                null);
+    }
+
+    /**
+     * Queries root documents information.
+     * @param columnNames Column names defined in
+     *     {@link android.provider.DocumentsContract.Document}.
+     * @return Database cursor.
+     */
+    Cursor queryRootDocuments(String[] columnNames) {
+        return mDatabase.query(
+                TABLE_DOCUMENTS,
+                columnNames,
+                COLUMN_ROW_STATE + " IN (?, ?)",
+                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED),
+                null,
+                null,
+                null);
+    }
+
+    /**
+     * Queries documents information.
+     * @param columnNames Column names defined in
+     *     {@link android.provider.DocumentsContract.Document}.
+     * @return Database cursor.
+     */
+    Cursor queryChildDocuments(String[] columnNames, String parentDocumentId) {
+        return mDatabase.query(
+                TABLE_DOCUMENTS,
+                columnNames,
+                COLUMN_ROW_STATE + " IN (?, ?) AND " + COLUMN_PARENT_DOCUMENT_ID + " = ?",
+                strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED, parentDocumentId),
+                null,
+                null,
+                null);
+    }
+
+    /**
+     * Remove all rows belong to a device.
+     * @param deviceId Device ID.
+     */
+    void removeDeviceRows(int deviceId) {
+        deleteDocumentsAndRoots(COLUMN_DEVICE_ID + "=?", strings(deviceId));
+    }
+
+    /**
+     * Gets identifier from document ID.
+     * @param documentId Document ID.
+     * @return Identifier.
+     */
+    Identifier createIdentifier(String documentId) {
+        // Currently documentId is old format.
+        final Identifier oldIdentifier = Identifier.createFromDocumentId(documentId);
+        final String selection;
+        final String[] args;
+        if (oldIdentifier.mObjectHandle == CursorHelper.DUMMY_HANDLE_FOR_ROOT) {
+            selection = COLUMN_DEVICE_ID + "= ? AND " +
+                    COLUMN_ROW_STATE + " IN (?, ?) AND " +
+                    COLUMN_STORAGE_ID + "= ? AND " +
+                    COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
+            args = strings(
+                    oldIdentifier.mDeviceId,
+                    ROW_STATE_VALID,
+                    ROW_STATE_INVALIDATED,
+                    oldIdentifier.mStorageId);
+        } else {
+            selection = COLUMN_DEVICE_ID + "= ? AND " +
+                    COLUMN_ROW_STATE + " IN (?, ?) AND " +
+                    COLUMN_STORAGE_ID + "= ? AND " +
+                    COLUMN_OBJECT_HANDLE + " = ?";
+            args = strings(
+                    oldIdentifier.mDeviceId,
+                    ROW_STATE_VALID,
+                    ROW_STATE_INVALIDATED,
+                    oldIdentifier.mStorageId,
+                    oldIdentifier.mObjectHandle);
+        }
+
+        final Cursor cursor = mDatabase.query(
+                TABLE_DOCUMENTS,
+                strings(Document.COLUMN_DOCUMENT_ID),
+                selection,
+                args,
+                null,
+                null,
+                null,
+                "1");
+        try {
+            if (cursor.getCount() == 0) {
+                return oldIdentifier;
+            } else {
+                cursor.moveToNext();
+                return new Identifier(
+                        oldIdentifier.mDeviceId,
+                        oldIdentifier.mStorageId,
+                        oldIdentifier.mObjectHandle,
+                        cursor.getString(0));
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Starts adding new documents.
+     * The methods decides mapping mode depends on if all documents under the given parent have MTP
+     * identifier or not. If all the documents have MTP identifier, it uses the identifier to find
+     * a corresponding existing row. Otherwise it does heuristic.
+     *
+     * @param selection Query matches valid documents.
+     * @param arg Argument for selection.
+     * @return Mapping mode.
+     */
+    int startAddingDocuments(String selection, String arg) {
+        mDatabase.beginTransaction();
+        try {
+            // Delete all pending rows.
+            deleteDocumentsAndRoots(
+                    selection + " AND " + COLUMN_ROW_STATE + "=?", strings(arg, ROW_STATE_PENDING));
+
+            // Set all documents as invalidated.
+            final ContentValues values = new ContentValues();
+            values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
+            mDatabase.update(TABLE_DOCUMENTS, values, selection, new String[] { arg });
+
+            // If we have rows that does not have MTP identifier, do heuristic mapping by name.
+            final boolean useNameForResolving = DatabaseUtils.queryNumEntries(
+                    mDatabase,
+                    TABLE_DOCUMENTS,
+                    selection + " AND " + COLUMN_STORAGE_ID + " IS NULL",
+                    new String[] { arg }) > 0;
+            mDatabase.setTransactionSuccessful();
+            return useNameForResolving ? MAP_BY_NAME : MAP_BY_MTP_IDENTIFIER;
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    /**
+     * Puts the documents into the database.
+     * If the mapping mode is not heuristic, it just adds the rows to the database or updates the
+     * existing rows with the new values. If the mapping mode is heuristic, it adds some new rows as
+     * 'pending' state when that rows may be corresponding to existing 'invalidated' rows. Then
+     * {@link #stopAddingDocuments(String, String, String)} turns the pending rows into 'valid'
+     * rows. If the methods adds rows to database, it updates valueList with correct document ID.
+     *
+     * @param valuesList Values for documents to be stored in the database.
+     * @param selection SQL where closure to select rows that shares the same parent.
+     * @param arg Argument for selection SQL.
+     * @param heuristic Whether the mapping mode is heuristic.
+     * @return Whether the method adds new rows.
+     */
+    boolean putDocuments(
+            ContentValues[] valuesList,
+            String selection,
+            String arg,
+            boolean heuristic,
+            String mappingKey) {
+        boolean added = false;
+        mDatabase.beginTransaction();
+        try {
+            for (final ContentValues values : valuesList) {
+                final Cursor candidateCursor = mDatabase.query(
+                        TABLE_DOCUMENTS,
+                        strings(Document.COLUMN_DOCUMENT_ID),
+                        selection + " AND " +
+                        COLUMN_ROW_STATE + "=? AND " +
+                        mappingKey + "=?",
+                        strings(arg, ROW_STATE_INVALIDATED, values.getAsString(mappingKey)),
+                        null,
+                        null,
+                        null,
+                        "1");
+                try {
+                    final long rowId;
+                    if (candidateCursor.getCount() == 0) {
+                        rowId = mDatabase.insert(TABLE_DOCUMENTS, null, values);
+                        if (rowId == -1) {
+                            throw new SQLiteException("Failed to put a document into database.");
+                        }
+                        added = true;
+                    } else if (!heuristic) {
+                        candidateCursor.moveToNext();
+                        final String documentId = candidateCursor.getString(0);
+                        rowId = mDatabase.update(
+                                TABLE_DOCUMENTS,
+                                values,
+                                SELECTION_DOCUMENT_ID,
+                                strings(documentId));
+                    } else {
+                        values.put(COLUMN_ROW_STATE, ROW_STATE_PENDING);
+                        rowId = mDatabase.insert(TABLE_DOCUMENTS, null, values);
+                    }
+                    // Document ID is a primary integer key of the table. So the returned row
+                    // IDs should be same with the document ID.
+                    values.put(Document.COLUMN_DOCUMENT_ID, rowId);
+                } finally {
+                    candidateCursor.close();
+                }
+            }
+
+            mDatabase.setTransactionSuccessful();
+            return added;
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    /**
+     * Puts extra information for root documents.
+     * @param values Values containing extra information.
+     */
+    void putRootExtra(ContentValues values) {
+        mDatabase.replace(TABLE_ROOT_EXTRA, null, values);
+    }
+
+    /**
+     * Maps 'pending' document and 'invalidated' document that shares the same column of groupKey.
+     * If the database does not find corresponding 'invalidated' document, it just removes
+     * 'invalidated' document from the database.
+     * @param selection Query to select rows for resolving.
+     * @param arg Argument for selection SQL.
+     * @param groupKey Column name used to find corresponding rows.
+     * @return Whether the methods adds or removed visible rows.
+     */
+    boolean stopAddingDocuments(String selection, String arg, String groupKey) {
+        mDatabase.beginTransaction();
+        try {
+            // Get 1-to-1 mapping of invalidated document and pending document.
+            final String invalidatedIdQuery = createStateFilter(
+                    ROW_STATE_INVALIDATED, Document.COLUMN_DOCUMENT_ID);
+            final String pendingIdQuery = createStateFilter(
+                    ROW_STATE_PENDING, Document.COLUMN_DOCUMENT_ID);
+            // SQL should be like:
+            // SELECT group_concat(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END),
+            //        group_concat(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END)
+            // WHERE device_id = ? AND parent_document_id IS NULL
+            // GROUP BY display_name
+            // HAVING count(CASE WHEN raw_state = 1 THEN document_id ELSE NULL END) = 1 AND
+            //        count(CASE WHEN raw_state = 2 THEN document_id ELSE NULL END) = 1
+            final Cursor mergingCursor = mDatabase.query(
+                    TABLE_DOCUMENTS,
+                    new String[] {
+                            "group_concat(" + invalidatedIdQuery + ")",
+                            "group_concat(" + pendingIdQuery + ")"
+                    },
+                    selection,
+                    strings(arg),
+                    groupKey,
+                    "count(" + invalidatedIdQuery + ") = 1 AND count(" + pendingIdQuery + ") = 1",
+                    null);
+
+            final ContentValues values = new ContentValues();
+            while (mergingCursor.moveToNext()) {
+                final String invalidatedId = mergingCursor.getString(0);
+                final String pendingId = mergingCursor.getString(1);
+
+                // Obtain the new values including the latest object handle from mapping row.
+                getFirstRow(
+                        TABLE_DOCUMENTS,
+                        SELECTION_DOCUMENT_ID,
+                        new String[] { pendingId },
+                        values);
+                values.remove(Document.COLUMN_DOCUMENT_ID);
+                values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
+                mDatabase.update(
+                        TABLE_DOCUMENTS,
+                        values,
+                        SELECTION_DOCUMENT_ID,
+                        new String[] { invalidatedId });
+
+                getFirstRow(
+                        TABLE_ROOT_EXTRA,
+                        SELECTION_ROOT_ID,
+                        new String[] { pendingId },
+                        values);
+                if (values.size() > 0) {
+                    values.remove(Root.COLUMN_ROOT_ID);
+                    mDatabase.update(
+                            TABLE_ROOT_EXTRA,
+                            values,
+                            SELECTION_ROOT_ID,
+                            new String[] { invalidatedId });
+                }
+
+                // Delete 'pending' row.
+                deleteDocumentsAndRoots(SELECTION_DOCUMENT_ID, new String[] { pendingId });
+            }
+            mergingCursor.close();
+
+            boolean changed = false;
+
+            // Delete all invalidated rows that cannot be mapped.
+            if (deleteDocumentsAndRoots(
+                    COLUMN_ROW_STATE + " = ? AND " + selection,
+                    strings(ROW_STATE_INVALIDATED, arg))) {
+                changed = true;
+            }
+
+            // The database cannot find old document ID for the pending rows.
+            // Turn the all pending rows into valid state, which means the rows become to be
+            // valid with new document ID.
+            values.clear();
+            values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
+            if (mDatabase.update(
+                    TABLE_DOCUMENTS,
+                    values,
+                    COLUMN_ROW_STATE + " = ? AND " + selection,
+                    strings(ROW_STATE_PENDING, arg)) != 0) {
+                changed = true;
+            }
+            mDatabase.setTransactionSuccessful();
+            return changed;
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    /**
+     * Clears MTP related identifier.
+     * It clears MTP's object handle and storage ID that are not stable over MTP sessions and mark
+     * the all documents as 'invalidated'. It also remove 'pending' rows as adding is cancelled
+     * now.
+     */
+    void clearMapping() {
+        mDatabase.beginTransaction();
+        try {
+            deleteDocumentsAndRoots(COLUMN_ROW_STATE + " = ?", strings(ROW_STATE_PENDING));
+            final ContentValues values = new ContentValues();
+            values.putNull(COLUMN_OBJECT_HANDLE);
+            values.putNull(COLUMN_STORAGE_ID);
+            values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
+            mDatabase.update(TABLE_DOCUMENTS, values, null, null);
+            mDatabase.setTransactionSuccessful();
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    /**
+     * {@link android.database.sqlite.SQLiteDatabase#beginTransaction()}
+     */
+    void beginTransaction() {
+        mDatabase.beginTransaction();
+    }
+
+    /**
+     * {@link android.database.sqlite.SQLiteDatabase#setTransactionSuccessful()}
+     */
+    void setTransactionSuccessful() {
+        mDatabase.setTransactionSuccessful();
+    }
+
+    /**
+     * {@link android.database.sqlite.SQLiteDatabase#endTransaction()}
+     */
+    void endTransaction() {
+        mDatabase.endTransaction();
+    }
+
+    /**
+     * Deletes a document, and its root information if the document is a root document.
+     * @param selection Query to select documents.
+     * @param args Arguments for selection.
+     * @return Whether the method deletes rows.
+     */
+    private boolean deleteDocumentsAndRoots(String selection, String[] args) {
+        mDatabase.beginTransaction();
+        try {
+            int deleted = 0;
+            deleted += mDatabase.delete(
+                    TABLE_ROOT_EXTRA,
+                    Root.COLUMN_ROOT_ID + " IN (" + SQLiteQueryBuilder.buildQueryString(
+                            false,
+                            TABLE_DOCUMENTS,
+                            new String[] { Document.COLUMN_DOCUMENT_ID },
+                            selection,
+                            null,
+                            null,
+                            null,
+                            null) + ")",
+                    args);
+            deleted += mDatabase.delete(TABLE_DOCUMENTS, selection, args);
+            mDatabase.setTransactionSuccessful();
+            return deleted != 0;
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    /**
+     * Obtains values of the first row for the query.
+     * @param values ContentValues that the values are stored to.
+     * @param table Target table.
+     * @param selection Query to select rows.
+     * @param args Argument for query.
+     */
+    private void getFirstRow(String table, String selection, String[] args, ContentValues values) {
+        values.clear();
+        final Cursor cursor = mDatabase.query(table, null, selection, args, null, null, null, "1");
+        if (cursor.getCount() == 0) {
+            return;
+        }
+        cursor.moveToNext();
+        DatabaseUtils.cursorRowToContentValues(cursor, values);
+        cursor.close();
+    }
+
+    /**
+     * Gets SQL expression that represents the given value or NULL depends on the row state.
+     * @param state Expected row state.
+     * @param a SQL value.
+     * @return Expression that represents a if the row state is expected one, and represents NULL
+     *     otherwise.
+     */
+    private static String createStateFilter(int state, String a) {
+        return "CASE WHEN " + COLUMN_ROW_STATE + " = " + Integer.toString(state) +
+                " THEN " + a + " ELSE NULL END";
+    }
+
+    /**
+     * Converts values into string array.
+     * @param args Values converted into string array.
+     * @return String array.
+     */
+    private static String[] strings(Object... args) {
+        final String[] results = new String[args.length];
+        for (int i = 0; i < args.length; i++) {
+            results[i] = Objects.toString(args[i]);
+        }
+        return results;
+    }
+}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 7883e61..f0f8161 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -62,6 +62,7 @@
     private Map<Integer, DeviceToolkit> mDeviceToolkits;
     private RootScanner mRootScanner;
     private Resources mResources;
+    private MtpDatabase mDatabase;
 
     /**
      * Provides singleton instance to MtpDocumentsService.
@@ -77,17 +78,23 @@
         mMtpManager = new MtpManager(getContext());
         mResolver = getContext().getContentResolver();
         mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
-        mRootScanner = new RootScanner(mResolver, mMtpManager);
+        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_FILE);
+        mRootScanner = new RootScanner(mResolver, mResources, mMtpManager, mDatabase);
         return true;
     }
 
     @VisibleForTesting
-    void onCreateForTesting(Resources resources, MtpManager mtpManager, ContentResolver resolver) {
+    void onCreateForTesting(
+            Resources resources,
+            MtpManager mtpManager,
+            ContentResolver resolver,
+            MtpDatabase database) {
         mResources = resources;
         mMtpManager = mtpManager;
         mResolver = resolver;
         mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
-        mRootScanner = new RootScanner(mResolver, mMtpManager);
+        mDatabase = database;
+        mRootScanner = new RootScanner(mResolver, mResources, mMtpManager, mDatabase);
     }
 
     @Override
@@ -95,17 +102,7 @@
         if (projection == null) {
             projection = MtpDocumentsProvider.DEFAULT_ROOT_PROJECTION;
         }
-        final MatrixCursor cursor = new MatrixCursor(projection);
-        final MtpRoot[] roots = mRootScanner.getRoots();
-        for (final MtpRoot root : roots) {
-            final Identifier rootIdentifier = new Identifier(root.mDeviceId, root.mStorageId);
-            final MatrixCursor.RowBuilder builder = cursor.newRow();
-            builder.add(Root.COLUMN_ROOT_ID, rootIdentifier.toRootId());
-            builder.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE);
-            builder.add(Root.COLUMN_TITLE, root.getRootName(mResources));
-            builder.add(Root.COLUMN_DOCUMENT_ID, rootIdentifier.toDocumentId());
-            builder.add(Root.COLUMN_AVAILABLE_BYTES , root.mFreeSpace);
-        }
+        final Cursor cursor = mDatabase.queryRoots(projection);
         cursor.setNotificationUri(
                 mResolver, DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY));
         return cursor;
@@ -158,7 +155,7 @@
         if (projection == null) {
             projection = MtpDocumentsProvider.DEFAULT_DOCUMENT_PROJECTION;
         }
-        final Identifier parentIdentifier = Identifier.createFromDocumentId(parentDocumentId);
+        final Identifier parentIdentifier = mDatabase.createIdentifier(parentDocumentId);
         try {
             return getDocumentLoader(parentIdentifier).queryChildDocuments(
                     projection, parentIdentifier);
@@ -258,7 +255,7 @@
 
     void openDevice(int deviceId) throws IOException {
         mMtpManager.openDevice(deviceId);
-        mDeviceToolkits.put(deviceId, new DeviceToolkit(mMtpManager, mResolver));
+        mDeviceToolkits.put(deviceId, new DeviceToolkit(mMtpManager, mResolver, mDatabase));
         mRootScanner.scanNow();
     }
 
@@ -266,14 +263,16 @@
         // TODO: Flush the device before closing (if not closed externally).
         getDeviceToolkit(deviceId).mDocumentLoader.clearTasks();
         mDeviceToolkits.remove(deviceId);
+        mDatabase.removeDeviceRows(deviceId);
         mMtpManager.closeDevice(deviceId);
-        mRootScanner.scanNow();
+        mRootScanner.notifyChange();
     }
 
-    void closeAllDevices() {
+    void close() throws InterruptedException {
         boolean closed = false;
         for (int deviceId : mMtpManager.getOpenedDeviceIds()) {
             try {
+                mDatabase.removeDeviceRows(deviceId);
                 mMtpManager.closeDevice(deviceId);
                 getDeviceToolkit(deviceId).mDocumentLoader.clearTasks();
                 closed = true;
@@ -282,8 +281,10 @@
             }
         }
         if (closed) {
-            mRootScanner.scanNow();
+            mRootScanner.notifyChange();
         }
+        mRootScanner.close();
+        mDatabase.close();
     }
 
     boolean hasOpenedDevices() {
@@ -317,9 +318,9 @@
         public final PipeManager mPipeManager;
         public final DocumentLoader mDocumentLoader;
 
-        public DeviceToolkit(MtpManager manager, ContentResolver resolver) {
+        public DeviceToolkit(MtpManager manager, ContentResolver resolver, MtpDatabase database) {
             mPipeManager = new PipeManager();
-            mDocumentLoader = new DocumentLoader(manager, resolver);
+            mDocumentLoader = new DocumentLoader(manager, resolver, database);
         }
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
index 328f618..2d1af26 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
@@ -79,9 +79,13 @@
     @Override
     public void onDestroy() {
         final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
-        provider.closeAllDevices();
         unregisterReceiver(mReceiver);
         mReceiver = null;
+        try {
+            provider.close();
+        } catch (InterruptedException e) {
+            Log.e(MtpDocumentsProvider.TAG, e.getMessage());
+        }
         super.onDestroy();
     }
 
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
index ffab176..d9ed4ab 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
@@ -1,14 +1,14 @@
 package com.android.mtp;
 
 import android.content.ContentResolver;
+import android.content.res.Resources;
+import android.database.sqlite.SQLiteException;
 import android.net.Uri;
 import android.os.Process;
 import android.provider.DocumentsContract;
 import android.util.Log;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
 
 final class RootScanner {
     /**
@@ -28,18 +28,28 @@
     private final static long SHORT_POLLING_TIMES = 10;
 
     final ContentResolver mResolver;
+    final Resources mResources;
     final MtpManager mManager;
-    MtpRoot[] mLastRoots = new MtpRoot[0];
+    final MtpDatabase mDatabase;
+    boolean mClosed = false;
     int mPollingCount;
-    boolean mHasBackgroundTask = false;
+    Thread mBackgroundThread;
 
-    RootScanner(ContentResolver resolver, MtpManager manager) {
+    RootScanner(
+            ContentResolver resolver,
+            Resources resources,
+            MtpManager manager,
+            MtpDatabase database) {
         mResolver = resolver;
+        mResources = resources;
         mManager = manager;
+        mDatabase = database;
     }
 
-    synchronized MtpRoot[] getRoots() {
-        return mLastRoots;
+    void notifyChange() {
+        final Uri uri =
+                DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
+        mResolver.notifyChange(uri, null, false);
     }
 
     /**
@@ -47,26 +57,29 @@
      * If the background thread has already gone, it restarts another background thread.
      */
     synchronized void scanNow() {
+        if (mClosed) {
+            return;
+        }
         mPollingCount = 0;
-        if (!mHasBackgroundTask) {
-            mHasBackgroundTask = true;
-            new BackgroundLoaderThread().start();
+        if (mBackgroundThread == null) {
+            mBackgroundThread = new BackgroundLoaderThread();
+            mBackgroundThread.start();
         } else {
             notify();
         }
     }
 
-    private MtpRoot[] createRoots(int[] deviceIds) {
-        final ArrayList<MtpRoot> roots = new ArrayList<>();
-        for (final int deviceId : deviceIds) {
-            try {
-                roots.addAll(Arrays.asList(mManager.getRoots(deviceId)));
-            } catch (IOException error) {
-                // Skip device that return error.
-                Log.d(MtpDocumentsProvider.TAG, error.getMessage());
+    void close() throws InterruptedException {
+        Thread thread;
+        synchronized (this) {
+            mClosed = true;
+            thread = mBackgroundThread;
+            if (mBackgroundThread == null) {
+                return;
             }
+            notify();
         }
-        return roots.toArray(new MtpRoot[roots.size()]);
+        thread.join();
     }
 
     private final class BackgroundLoaderThread extends Thread {
@@ -74,18 +87,29 @@
         public void run() {
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
             synchronized (RootScanner.this) {
-                while (true) {
+                while (!mClosed) {
                     final int[] deviceIds = mManager.getOpenedDeviceIds();
-                    final MtpRoot[] newRoots = createRoots(deviceIds);
-                    if (!Arrays.equals(mLastRoots, newRoots)) {
-                        final Uri uri =
-                                DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
-                        mResolver.notifyChange(uri, null, false);
-                        mLastRoots = newRoots;
-                    }
                     if (deviceIds.length == 0) {
                         break;
                     }
+                    boolean changed = false;
+                    for (int deviceId : deviceIds) {
+                        mDatabase.startAddingRootDocuments(deviceId);
+                        try {
+                            changed = mDatabase.putRootDocuments(
+                                    deviceId, mResources, mManager.getRoots(deviceId)) || changed;
+                        } catch (IOException|SQLiteException exp) {
+                            // The error may happen on the device. We would like to continue getting
+                            // roots for other devices.
+                            Log.e(MtpDocumentsProvider.TAG, exp.getMessage());
+                            continue;
+                        } finally {
+                            changed = mDatabase.stopAddingRootDocuments(deviceId) || changed;
+                        }
+                    }
+                    if (changed) {
+                        notifyChange();
+                    }
                     mPollingCount++;
                     try {
                         // Use SHORT_POLLING_PERIOD for the first SHORT_POLLING_TIMES because it is
@@ -99,7 +123,7 @@
                     }
                 }
 
-                mHasBackgroundTask = false;
+                mBackgroundThread = null;
             }
         }
     }
diff --git a/packages/MtpDocumentsProvider/tests/AndroidManifest.xml b/packages/MtpDocumentsProvider/tests/AndroidManifest.xml
index 28ad3f4..e1307e9 100644
--- a/packages/MtpDocumentsProvider/tests/AndroidManifest.xml
+++ b/packages/MtpDocumentsProvider/tests/AndroidManifest.xml
@@ -18,7 +18,4 @@
     <instrumentation android:name="com.android.mtp.TestResultInstrumentation"
         android:targetPackage="com.android.mtp"
         android:label="Tests for MtpDocumentsProvider with the UI for output." />
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.android.mtp"
-        android:label="Tests for MtpDocumentsProvider." />
 </manifest>
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
index a012d7f..a80eb51 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
@@ -22,26 +22,37 @@
 import android.net.Uri;
 import android.provider.DocumentsContract;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 
 import java.io.IOException;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
-@SmallTest
+@MediumTest
 public class DocumentLoaderTest extends AndroidTestCase {
+    private MtpDatabase mDatabase;
     private BlockableTestMtpManager mManager;
     private TestContentResolver mResolver;
     private DocumentLoader mLoader;
-    final private Identifier mParentIdentifier = new Identifier(0, 0, 0);
+    final private Identifier mParentIdentifier = new Identifier(0, 0, 0, "1");
 
     @Override
     public void setUp() {
+        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, new TestResources(), new MtpRoot[] {
+                new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "")
+        });
+        mDatabase.stopAddingRootDocuments(0);
         mManager = new BlockableTestMtpManager(getContext());
         mResolver = new TestContentResolver();
-        mLoader = new DocumentLoader(mManager, mResolver);
+        mLoader = new DocumentLoader(mManager, mResolver, mDatabase);
+    }
+
+    @Override
+    public void tearDown() {
+        mDatabase.close();
     }
 
     public void testBasic() throws Exception {
@@ -88,6 +99,7 @@
             childDocuments[i] = objectHandle;
             manager.setObjectInfo(0, new MtpObjectInfo.Builder()
                     .setObjectHandle(objectHandle)
+                    .setName(Integer.toString(i))
                     .build());
         }
         manager.setObjectHandles(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, childDocuments);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index 7bc9972..25dd1c8 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -20,6 +20,7 @@
 import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
 import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Root;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -27,9 +28,9 @@
 public class MtpDatabaseTest extends AndroidTestCase {
     private final String[] COLUMN_NAMES = new String[] {
         DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-        MtpDatabase.COLUMN_DEVICE_ID,
-        MtpDatabase.COLUMN_STORAGE_ID,
-        MtpDatabase.COLUMN_OBJECT_HANDLE,
+        MtpDatabaseConstants.COLUMN_DEVICE_ID,
+        MtpDatabaseConstants.COLUMN_STORAGE_ID,
+        MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
         DocumentsContract.Document.COLUMN_MIME_TYPE,
         DocumentsContract.Document.COLUMN_DISPLAY_NAME,
         DocumentsContract.Document.COLUMN_SUMMARY,
@@ -40,45 +41,100 @@
     };
 
     private final TestResources resources = new TestResources();
+    MtpDatabase mDatabase;
+
+    @Override
+    public void setUp() {
+        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+    }
 
     @Override
     public void tearDown() {
-        MtpDatabase.deleteDatabase(getContext());
+        mDatabase.close();
+        mDatabase = null;
     }
 
     public void testPutRootDocuments() throws Exception {
-        final MtpDatabase database = new MtpDatabase(getContext());
-        database.putRootDocuments(0, resources, new MtpRoot[] {
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 1, "Device", "Storage", 1000, 2000, ""),
-                new MtpRoot(0, 2, "Device", "Storage", 1000, 2000, ""),
-                new MtpRoot(0, 3, "Device", "/@#%&<>Storage", 1000, 2000,"")
+                new MtpRoot(0, 2, "Device", "Storage", 2000, 4000, ""),
+                new MtpRoot(0, 3, "Device", "/@#%&<>Storage", 3000, 6000,"")
         });
 
-        final Cursor cursor = database.queryRootDocuments(COLUMN_NAMES);
-        assertEquals(3, cursor.getCount());
+        {
+            final Cursor cursor = mDatabase.queryRootDocuments(COLUMN_NAMES);
+            assertEquals(3, cursor.getCount());
 
-        cursor.moveToNext();
-        assertEquals("documentId", 1, cursor.getInt(0));
-        assertEquals("deviceId", 0, cursor.getInt(1));
-        assertEquals("storageId", 1, cursor.getInt(2));
-        assertTrue("objectHandle", cursor.isNull(3));
-        assertEquals("mimeType", DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(4));
-        assertEquals("displayName", "Device Storage", cursor.getString(5));
-        assertTrue("summary", cursor.isNull(6));
-        assertTrue("lastModified", cursor.isNull(7));
-        assertTrue("icon", cursor.isNull(8));
-        assertEquals("flag", 0, cursor.getInt(9));
-        assertEquals("size", 1000, cursor.getInt(10));
+            cursor.moveToNext();
+            assertEquals("documentId", 1, cursor.getInt(0));
+            assertEquals("deviceId", 0, cursor.getInt(1));
+            assertEquals("storageId", 1, cursor.getInt(2));
+            assertTrue("objectHandle", cursor.isNull(3));
+            assertEquals("mimeType", DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(4));
+            assertEquals("displayName", "Device Storage", cursor.getString(5));
+            assertTrue("summary", cursor.isNull(6));
+            assertTrue("lastModified", cursor.isNull(7));
+            assertTrue("icon", cursor.isNull(8));
+            assertEquals("flag", 0, cursor.getInt(9));
+            assertEquals("size", 1000, cursor.getInt(10));
 
-        cursor.moveToNext();
-        assertEquals("documentId", 2, cursor.getInt(0));
-        assertEquals("displayName", "Device Storage", cursor.getString(5));
+            cursor.moveToNext();
+            assertEquals("documentId", 2, cursor.getInt(0));
+            assertEquals("displayName", "Device Storage", cursor.getString(5));
 
-        cursor.moveToNext();
-        assertEquals("documentId", 3, cursor.getInt(0));
-        assertEquals("displayName", "Device /@#%&<>Storage", cursor.getString(5));
+            cursor.moveToNext();
+            assertEquals("documentId", 3, cursor.getInt(0));
+            assertEquals("displayName", "Device /@#%&<>Storage", cursor.getString(5));
 
-        cursor.close();
+            cursor.close();
+        }
+
+        {
+            final Cursor cursor = mDatabase.queryRoots(new String [] {
+                    Root.COLUMN_ROOT_ID,
+                    Root.COLUMN_FLAGS,
+                    Root.COLUMN_ICON,
+                    Root.COLUMN_TITLE,
+                    Root.COLUMN_SUMMARY,
+                    Root.COLUMN_DOCUMENT_ID + "_",
+                    Root.COLUMN_AVAILABLE_BYTES,
+                    Root.COLUMN_CAPACITY_BYTES
+            });
+            assertEquals(3, cursor.getCount());
+
+            cursor.moveToNext();
+            assertEquals(1, cursor.getInt(0));
+            assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
+            assertTrue(cursor.isNull(2));
+            assertEquals("Device Storage", cursor.getString(3));
+            assertTrue(cursor.isNull(4));
+            assertEquals(1, cursor.getInt(5));
+            assertEquals(1000, cursor.getInt(6));
+            assertEquals(2000, cursor.getInt(7));
+
+            cursor.moveToNext();
+            assertEquals(2, cursor.getInt(0));
+            assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
+            assertTrue(cursor.isNull(2));
+            assertEquals("Device Storage", cursor.getString(3));
+            assertTrue(cursor.isNull(4));
+            assertEquals(2, cursor.getInt(5));
+            assertEquals(2000, cursor.getInt(6));
+            assertEquals(4000, cursor.getInt(7));
+
+            cursor.moveToNext();
+            assertEquals(3, cursor.getInt(0));
+            assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
+            assertTrue(cursor.isNull(2));
+            assertEquals("Device /@#%&<>Storage", cursor.getString(3));
+            assertTrue(cursor.isNull(4));
+            assertEquals(3, cursor.getInt(5));
+            assertEquals(3000, cursor.getInt(6));
+            assertEquals(6000, cursor.getInt(7));
+
+            cursor.close();
+        }
     }
 
     private MtpObjectInfo createDocument(int objectHandle, String name, int format, int size) {
@@ -91,15 +147,14 @@
     }
 
     public void testPutChildDocuments() throws Exception {
-        final MtpDatabase database = new MtpDatabase(getContext());
-
-        database.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        mDatabase.startAddingChildDocuments("parentId");
+        mDatabase.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
         });
 
-        final Cursor cursor = database.queryChildDocuments(COLUMN_NAMES, "parentId");
+        final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "parentId");
         assertEquals(3, cursor.getCount());
 
         cursor.moveToNext();
@@ -157,19 +212,24 @@
     }
 
     public void testRestoreIdForRootDocuments() throws Exception {
-        final MtpDatabase database = new MtpDatabase(getContext());
         final String[] columns = new String[] {
                 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-                MtpDatabase.COLUMN_STORAGE_ID,
+                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
-        database.putRootDocuments(0, resources, new MtpRoot[] {
-                new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
-                new MtpRoot(0, 101, "Device", "Storage B", 0, 0, "")
+        final String[] rootColumns = new String[] {
+                Root.COLUMN_ROOT_ID,
+                Root.COLUMN_AVAILABLE_BYTES
+        };
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage A", 1000, 0, ""),
+                new MtpRoot(0, 101, "Device", "Storage B", 1001, 0, "")
         });
 
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -182,10 +242,22 @@
             cursor.close();
         }
 
-        database.clearMapping();
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(2, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 1000, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 2, cursor.getInt(0));
+            assertEquals("availableBytes", 1001, cursor.getInt(1));
+            cursor.close();
+        }
+
+        mDatabase.clearMapping();
 
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -198,13 +270,26 @@
             cursor.close();
         }
 
-        database.putRootDocuments(0, resources, new MtpRoot[] {
-                new MtpRoot(0, 200, "Device", "Storage A", 0, 0, ""),
-                new MtpRoot(0, 202, "Device", "Storage C", 0, 0, "")
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(2, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 1000, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 2, cursor.getInt(0));
+            assertEquals("availableBytes", 1001, cursor.getInt(1));
+            cursor.close();
+        }
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 200, "Device", "Storage A", 2000, 0, ""),
+                new MtpRoot(0, 202, "Device", "Storage C", 2002, 0, "")
         });
 
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(3, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -221,10 +306,25 @@
             cursor.close();
         }
 
-        database.resolveRootDocuments(0);
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(3, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 1000, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 2, cursor.getInt(0));
+            assertEquals("availableBytes", 1001, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 4, cursor.getInt(0));
+            assertEquals("availableBytes", 2002, cursor.getInt(1));
+            cursor.close();
+        }
+
+        mDatabase.stopAddingRootDocuments(0);
 
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -236,24 +336,36 @@
             assertEquals("name", "Device Storage C", cursor.getString(2));
             cursor.close();
         }
+
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(2, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 2000, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 4, cursor.getInt(0));
+            assertEquals("availableBytes", 2002, cursor.getInt(1));
+            cursor.close();
+        }
     }
 
     public void testRestoreIdForChildDocuments() throws Exception {
-        final MtpDatabase database = new MtpDatabase(getContext());
         final String[] columns = new String[] {
                 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-                MtpDatabase.COLUMN_OBJECT_HANDLE,
+                MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
-        database.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        mDatabase.startAddingChildDocuments("parentId");
+        mDatabase.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
         });
-        database.clearMapping();
+        mDatabase.clearMapping();
 
         {
-            final Cursor cursor = database.queryChildDocuments(columns, "parentId");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
             assertEquals(3, cursor.getCount());
 
             cursor.moveToNext();
@@ -274,13 +386,14 @@
             cursor.close();
         }
 
-        database.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        mDatabase.startAddingChildDocuments("parentId");
+        mDatabase.putChildDocuments(0, "parentId", new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024),
         });
 
         {
-            final Cursor cursor = database.queryChildDocuments(columns, "parentId");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
             assertEquals(4, cursor.getCount());
 
             cursor.moveToPosition(3);
@@ -291,10 +404,10 @@
             cursor.close();
         }
 
-        database.resolveChildDocuments("parentId");
+        mDatabase.stopAddingChildDocuments("parentId");
 
         {
-            final Cursor cursor = database.queryChildDocuments(columns, "parentId");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
             assertEquals(2, cursor.getCount());
 
             cursor.moveToNext();
@@ -311,21 +424,26 @@
     }
 
     public void testRestoreIdForDifferentDevices() throws Exception {
-        final MtpDatabase database = new MtpDatabase(getContext());
         final String[] columns = new String[] {
                 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-                MtpDatabase.COLUMN_STORAGE_ID,
+                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
-        database.putRootDocuments(0, resources, new MtpRoot[] {
+        final String[] rootColumns = new String[] {
+                Root.COLUMN_ROOT_ID,
+                Root.COLUMN_AVAILABLE_BYTES
+        };
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.startAddingRootDocuments(1);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage", 0, 0, "")
         });
-        database.putRootDocuments(1, resources, new MtpRoot[] {
+        mDatabase.putRootDocuments(1, resources, new MtpRoot[] {
                 new MtpRoot(1, 100, "Device", "Storage", 0, 0, "")
         });
 
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -338,19 +456,33 @@
             cursor.close();
         }
 
-        database.clearMapping();
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(2, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 0, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 2, cursor.getInt(0));
+            assertEquals("availableBytes", 0, cursor.getInt(1));
+            cursor.close();
+        }
 
-        database.putRootDocuments(0, resources, new MtpRoot[] {
-                new MtpRoot(0, 200, "Device", "Storage", 0, 0, "")
+        mDatabase.clearMapping();
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.startAddingRootDocuments(1);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 200, "Device", "Storage", 2000, 0, "")
         });
-        database.putRootDocuments(1, resources, new MtpRoot[] {
-                new MtpRoot(1, 300, "Device", "Storage", 0, 0, "")
+        mDatabase.putRootDocuments(1, resources, new MtpRoot[] {
+                new MtpRoot(1, 300, "Device", "Storage", 3000, 0, "")
         });
-        database.resolveRootDocuments(0);
-        database.resolveRootDocuments(1);
+        mDatabase.stopAddingRootDocuments(0);
+        mDatabase.stopAddingRootDocuments(1);
 
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -362,31 +494,48 @@
             assertEquals("name", "Device Storage", cursor.getString(2));
             cursor.close();
         }
+
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(2, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 2000, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 2, cursor.getInt(0));
+            assertEquals("availableBytes", 3000, cursor.getInt(1));
+            cursor.close();
+        }
     }
 
     public void testRestoreIdForDifferentParents() throws Exception {
-        final MtpDatabase database = new MtpDatabase(getContext());
         final String[] columns = new String[] {
                 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-                MtpDatabase.COLUMN_OBJECT_HANDLE
+                MtpDatabaseConstants.COLUMN_OBJECT_HANDLE
         };
-        database.putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
+
+        mDatabase.startAddingChildDocuments("parentId1");
+        mDatabase.startAddingChildDocuments("parentId2");
+        mDatabase.putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        database.putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
+        mDatabase.putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
                 createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        database.clearMapping();
-        database.putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
+        mDatabase.clearMapping();
+
+        mDatabase.startAddingChildDocuments("parentId1");
+        mDatabase.startAddingChildDocuments("parentId2");
+        mDatabase.putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        database.putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
+        mDatabase.putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
                 createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        database.resolveChildDocuments("parentId1");
+        mDatabase.stopAddingChildDocuments("parentId1");
 
         {
-            final Cursor cursor = database.queryChildDocuments(columns, "parentId1");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId1");
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -394,7 +543,7 @@
             cursor.close();
         }
         {
-            final Cursor cursor = database.queryChildDocuments(columns, "parentId2");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId2");
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 2, cursor.getInt(0));
@@ -404,26 +553,36 @@
     }
 
     public void testClearMtpIdentifierBeforeResolveRootDocuments() {
-        final MtpDatabase database = new MtpDatabase(getContext());
         final String[] columns = new String[] {
                 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-                MtpDatabase.COLUMN_STORAGE_ID,
+                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
-        database.putRootDocuments(0, resources, new MtpRoot[] {
+        final String[] rootColumns = new String[] {
+                Root.COLUMN_ROOT_ID,
+                Root.COLUMN_AVAILABLE_BYTES
+        };
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage", 0, 0, ""),
         });
-        database.clearMapping();
-        database.putRootDocuments(0, resources, new MtpRoot[] {
-                new MtpRoot(0, 200, "Device", "Storage", 0, 0, ""),
+        mDatabase.clearMapping();
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 200, "Device", "Storage", 2000, 0, ""),
         });
-        database.clearMapping();
-        database.putRootDocuments(0, resources, new MtpRoot[] {
-                new MtpRoot(0, 300, "Device", "Storage", 0, 0, ""),
+        mDatabase.clearMapping();
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 300, "Device", "Storage", 3000, 0, ""),
         });
-        database.resolveRootDocuments(0);
+        mDatabase.stopAddingRootDocuments(0);
+
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 1, cursor.getInt(0));
@@ -431,26 +590,42 @@
             assertEquals("name", "Device Storage", cursor.getString(2));
             cursor.close();
         }
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 3000, cursor.getInt(1));
+            cursor.close();
+        }
     }
 
     public void testPutSameNameRootsAfterClearing() throws Exception {
-        final MtpDatabase database = new MtpDatabase(getContext());
         final String[] columns = new String[] {
                 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-                MtpDatabase.COLUMN_STORAGE_ID,
+                MtpDatabaseConstants.COLUMN_STORAGE_ID,
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
-        database.putRootDocuments(0, resources, new MtpRoot[] {
+        final String[] rootColumns = new String[] {
+                Root.COLUMN_ROOT_ID,
+                Root.COLUMN_AVAILABLE_BYTES
+        };
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
                 new MtpRoot(0, 100, "Device", "Storage", 0, 0, ""),
         });
-        database.clearMapping();
-        database.putRootDocuments(0, resources, new MtpRoot[] {
-                new MtpRoot(0, 200, "Device", "Storage", 0, 0, ""),
-                new MtpRoot(0, 201, "Device", "Storage", 0, 0, ""),
+        mDatabase.clearMapping();
+
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 200, "Device", "Storage", 2000, 0, ""),
+                new MtpRoot(0, 201, "Device", "Storage", 2001, 0, ""),
         });
-        database.resolveRootDocuments(0);
+        mDatabase.stopAddingRootDocuments(0);
+
         {
-            final Cursor cursor = database.queryRootDocuments(columns);
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
             assertEquals("documentId", 2, cursor.getInt(0));
@@ -462,5 +637,81 @@
             assertEquals("name", "Device Storage", cursor.getString(2));
             cursor.close();
         }
+        {
+            final Cursor cursor = mDatabase.queryRoots(rootColumns);
+            assertEquals(2, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 2, cursor.getInt(0));
+            assertEquals("availableBytes", 2000, cursor.getInt(1));
+            cursor.moveToNext();
+            assertEquals("rootId", 3, cursor.getInt(0));
+            assertEquals("availableBytes", 2001, cursor.getInt(1));
+            cursor.close();
+        }
+    }
+
+    public void testReplaceExistingRoots() {
+        // The client code should be able to replace existing rows with new information.
+        // Add one.
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
+        });
+        mDatabase.stopAddingRootDocuments(0);
+        // Replace it.
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage B", 1000, 1000, ""),
+        });
+        mDatabase.stopAddingRootDocuments(0);
+        {
+            final String[] columns = new String[] {
+                    DocumentsContract.Document.COLUMN_DOCUMENT_ID,
+                    MtpDatabaseConstants.COLUMN_STORAGE_ID,
+                    DocumentsContract.Document.COLUMN_DISPLAY_NAME
+            };
+            final Cursor cursor = mDatabase.queryRootDocuments(columns);
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("documentId", 1, cursor.getInt(0));
+            assertEquals("storageId", 100, cursor.getInt(1));
+            assertEquals("name", "Device Storage B", cursor.getString(2));
+            cursor.close();
+        }
+        {
+            final String[] columns = new String[] {
+                    Root.COLUMN_ROOT_ID,
+                    Root.COLUMN_AVAILABLE_BYTES
+            };
+            final Cursor cursor = mDatabase.queryRoots(columns);
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("rootId", 1, cursor.getInt(0));
+            assertEquals("availableBytes", 1000, cursor.getInt(1));
+            cursor.close();
+        }
+    }
+
+    public void _testFailToReplaceExisitingUnmappedRoots() {
+        // The client code should not be able to replace rows before resolving 'unmapped' rows.
+        // Add one.
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage A", 0, 0, ""),
+        });
+        mDatabase.clearMapping();
+        // Add one.
+        mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                new MtpRoot(0, 100, "Device", "Storage B", 1000, 1000, ""),
+        });
+        // Add one more before resolving unmapped documents.
+        try {
+            mDatabase.putRootDocuments(0, resources, new MtpRoot[] {
+                    new MtpRoot(0, 100, "Device", "Storage B", 1000, 1000, ""),
+            });
+            fail();
+        } catch (Throwable e) {
+            assertTrue(e instanceof Error);
+        }
     }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index 5765f0a..82e08cd 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -36,13 +36,24 @@
     private MtpDocumentsProvider mProvider;
     private TestMtpManager mMtpManager;
     private final TestResources mResources = new TestResources();
+    private MtpDatabase mDatabase;
 
     @Override
     public void setUp() throws IOException {
         mResolver = new TestContentResolver();
         mMtpManager = new TestMtpManager(getContext());
         mProvider = new MtpDocumentsProvider();
-        mProvider.onCreateForTesting(mResources, mMtpManager, mResolver);
+        mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        mProvider.onCreateForTesting(mResources, mMtpManager, mResolver, mDatabase);
+    }
+
+    @Override
+    public void tearDown() {
+        try {
+            mProvider.close();
+        } catch (InterruptedException e) {
+            fail();
+        }
     }
 
     public void testOpenAndCloseDevice() throws Exception {
@@ -96,26 +107,6 @@
         mResolver.waitForNotification(ROOTS_URI, 1);
     }
 
-    public void testCloseAllDevices() throws Exception {
-        mMtpManager.addValidDevice(0);
-        mMtpManager.setRoots(0, new MtpRoot[] {
-                new MtpRoot(
-                        0 /* deviceId */,
-                        1 /* storageId */,
-                        "Device A" /* device model name */,
-                        "Storage A" /* volume description */,
-                        1024 /* free space */,
-                        2048 /* total space */,
-                        "" /* no volume identifier */)
-        });
-        mProvider.closeAllDevices();
-        mProvider.openDevice(0);
-        mResolver.waitForNotification(ROOTS_URI, 1);
-
-        mProvider.closeAllDevices();
-        mResolver.waitForNotification(ROOTS_URI, 2);
-    }
-
     public void testQueryRoots() throws Exception {
         mMtpManager.addValidDevice(0);
         mMtpManager.addValidDevice(1);
@@ -146,7 +137,7 @@
             final Cursor cursor = mProvider.queryRoots(null);
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
-            assertEquals("0_1", cursor.getString(0));
+            assertEquals("1", cursor.getString(0));
             assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
             // TODO: Add storage icon for MTP devices.
             assertTrue(cursor.isNull(2) /* icon */);
@@ -162,7 +153,7 @@
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
             cursor.moveToNext();
-            assertEquals("1_1", cursor.getString(0));
+            assertEquals("2", cursor.getString(0));
             assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
             // TODO: Add storage icon for MTP devices.
             assertTrue(cursor.isNull(2) /* icon */);
@@ -170,13 +161,6 @@
             assertEquals("1_1_0", cursor.getString(4));
             assertEquals(2048, cursor.getInt(5));
         }
-
-        {
-            mProvider.closeAllDevices();
-            mResolver.waitForNotification(ROOTS_URI, 3);
-            final Cursor cursor = mProvider.queryRoots(null);
-            assertEquals(0, cursor.getCount());
-        }
     }
 
     public void testQueryRoots_error() throws Exception {
@@ -201,7 +185,7 @@
             final Cursor cursor = mProvider.queryRoots(null);
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
-            assertEquals("1_1", cursor.getString(0));
+            assertEquals("1", cursor.getString(0));
             assertEquals(Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE, cursor.getInt(1));
             // TODO: Add storage icon for MTP devices.
             assertTrue(cursor.isNull(2) /* icon */);
@@ -216,6 +200,7 @@
         mProvider.openDevice(0);
         mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
                 .setObjectHandle(2)
+                .setStorageId(1)
                 .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
                 .setName("image.jpg")
                 .setDateModified(1422716400000L)
@@ -226,6 +211,7 @@
         assertEquals(1, cursor.getCount());
 
         cursor.moveToNext();
+
         assertEquals("0_1_2", cursor.getString(0));
         assertEquals("image/jpeg", cursor.getString(1));
         assertEquals("image.jpg", cursor.getString(2));
@@ -243,6 +229,7 @@
         mProvider.openDevice(0);
         mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
                 .setObjectHandle(2)
+                .setStorageId(1)
                 .setFormat(MtpConstants.FORMAT_ASSOCIATION)
                 .setName("directory")
                 .setDateModified(1422716400000L)
@@ -293,6 +280,12 @@
         mProvider.openDevice(0);
         mMtpManager.setObjectHandles(0, 0, -1, new int[] { 1 });
 
+        mDatabase.startAddingRootDocuments(0);
+        mDatabase.putRootDocuments(0, mResources, new MtpRoot[] {
+                new MtpRoot(0, 0, "Device", "Storage", 1000, 1000, "")
+        });
+        mDatabase.stopAddingRootDocuments(0);
+
         mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder()
                 .setObjectHandle(1)
                 .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
index 53018cc..7c947f5 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
@@ -19,15 +19,14 @@
 import android.mtp.MtpObjectInfo;
 import android.os.ParcelFileDescriptor;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
 
 import java.io.IOException;
-import java.util.Date;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
-@SmallTest
+@MediumTest
 public class PipeManagerTest extends AndroidTestCase {
     private static final byte[] HELLO_BYTES = new byte[] { 'h', 'e', 'l', 'l', 'o' };
 
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
index 3d92cc2..3833799 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -96,7 +96,7 @@
         if (mRoots.containsKey(deviceId)) {
             return mRoots.get(deviceId);
         } else {
-            throw new IOException("getRoots error");
+            throw new IOException("getRoots error: " + Integer.toString(deviceId));
         }
     }
 
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java
index a243375..0fb0f34 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResultInstrumentation.java
@@ -12,8 +12,20 @@
 
     @Override
     public void onCreate(Bundle arguments) {
+        if (arguments == null) {
+            arguments = new Bundle();
+        }
+        final boolean includeRealDeviceTest =
+                Boolean.parseBoolean(arguments.getString("realDeviceTest", "false"));
+        if (!includeRealDeviceTest) {
+            arguments.putString("notAnnotation", "com.android.mtp.RealDeviceTest");
+        }
         super.onCreate(arguments);
-        addTestListener(this);
+        if (includeRealDeviceTest) {
+            // Show the test result by using activity because we need to disconnect USB cable
+            // from adb host while testing with real MTP device.
+            addTestListener(this);
+        }
     }
 
     @Override
diff --git a/core/res/res/layout/docked_stack_divider.xml b/packages/PrintSpooler/res/drawable/ic_add.xml
similarity index 66%
copy from core/res/res/layout/docked_stack_divider.xml
copy to packages/PrintSpooler/res/drawable/ic_add.xml
index aa6e68d..1442b1b 100644
--- a/core/res/res/layout/docked_stack_divider.xml
+++ b/packages/PrintSpooler/res/drawable/ic_add.xml
@@ -14,8 +14,12 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="@dimen/docked_stack_divider_thickness"
-        android:layout_height="match_parent"
-        android:background="@android:color/black"
-        />
+<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:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
+        android:fillColor="#FFFFFF"/>
+</vector>
\ No newline at end of file
diff --git a/packages/PrintSpooler/res/drawable/ic_search.xml b/packages/PrintSpooler/res/drawable/ic_search.xml
deleted file mode 100644
index 991fa38b..0000000
--- a/packages/PrintSpooler/res/drawable/ic_search.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:autoMirrored="true">
-
-    <item
-        android:state_checked="true">
-        <bitmap
-            android:src="@*android:drawable/ic_menu_search"
-            android:tint="?android:attr/colorControlActivated">
-        </bitmap>
-    </item>
-
-    <item
-        android:state_pressed="true">
-        <bitmap
-            android:src="@*android:drawable/ic_menu_search"
-            android:tint="?android:attr/colorControlActivated">
-        </bitmap>
-    </item>
-
-    <item>
-        <bitmap
-            android:src="@*android:drawable/ic_menu_search"
-            android:tint="?android:attr/colorControlNormal">
-        </bitmap>
-    </item>
-
-</selector>
diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml
index 6b8aa47..a2f710d 100644
--- a/packages/PrintSpooler/res/layout/print_activity.xml
+++ b/packages/PrintSpooler/res/layout/print_activity.xml
@@ -69,7 +69,9 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="16dip"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="?android:attr/textColorPrimary">
+            android:textColor="?android:attr/textColorPrimary"
+            android:singleLine="true"
+            android:ellipsize="end">
         </TextView>
 
         <TextView
@@ -87,7 +89,9 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="16dip"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="?android:attr/textColorPrimary">
+            android:textColor="?android:attr/textColorPrimary"
+            android:singleLine="true"
+            android:ellipsize="end">
         </TextView>
 
     </LinearLayout>
diff --git a/packages/PrintSpooler/res/layout/printer_dropdown_prompt.xml b/packages/PrintSpooler/res/layout/printer_dropdown_prompt.xml
new file mode 100644
index 0000000..11fef2d
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/printer_dropdown_prompt.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content"
+      android:textAppearance="?android:attr/textAppearanceMedium"
+      android:textIsSelectable="false"
+      android:textColor="?android:attr/textColorPrimary"
+      android:paddingStart="20dip"
+      android:paddingEnd="8dip"
+      android:minHeight="56dip"
+      android:orientation="horizontal"
+      android:text="@string/destination_default_text"
+      android:gravity="start|center_vertical" />
diff --git a/packages/PrintSpooler/res/menu/select_printer_activity.xml b/packages/PrintSpooler/res/menu/select_printer_activity.xml
index 8da5769..15cc139 100644
--- a/packages/PrintSpooler/res/menu/select_printer_activity.xml
+++ b/packages/PrintSpooler/res/menu/select_printer_activity.xml
@@ -19,7 +19,7 @@
     <item
         android:id="@+id/action_search"
         android:title="@string/search"
-        android:icon="@*android:drawable/ic_search"
+        android:icon="@*android:drawable/ic_search_api_material"
         android:actionViewClass="android.widget.SearchView"
         android:showAsAction="ifRoom|collapseActionView"
         android:alphabeticShortcut="f"
@@ -29,7 +29,7 @@
     <item
         android:id="@+id/action_add_printer"
         android:title="@string/print_add_printer"
-        android:icon="@*android:drawable/create_contact"
+        android:icon="@drawable/ic_add"
         android:showAsAction="ifRoom"
         android:alphabeticShortcut="a">
     </item>
diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml
index 0cfa0de..cf13374 100644
--- a/packages/PrintSpooler/res/values-af/strings.xml
+++ b/packages/PrintSpooler/res/values-af/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Geen drukkers gekry nie"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Druk tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kanselleer tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met drukker nie"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie beskikbaar nie"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gebruik <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Jou dokument kan dalk deur een of meer bedieners op pad na die drukker gaan."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Swart en wit"</item>
     <item msgid="2762241247228983754">"Kleur"</item>
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
index 72fc67b..18c90f5 100644
--- a/packages/PrintSpooler/res/values-am/strings.xml
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"ምንም አታሚዎች አልተገኙም"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በማተም ላይ"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በመተው ላይ"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ከአታሚ ጋር ምንም ግንኙነት የለም"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"አይታወቅም"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – አይገኝም"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ይጠቀሙ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ሰነድዎ ወደ አታሚው በሚሄድበት ወቅት በአንድ ወይም ከዚያ በላይ አገልጋዮች ውስጥ ሊያልፍ ይችላል።"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"ጥቁር እና ነጭ"</item>
     <item msgid="2762241247228983754">"ቀለም"</item>
diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml
index e28c7bd..2d87498c 100644
--- a/packages/PrintSpooler/res/values-ar/strings.xml
+++ b/packages/PrintSpooler/res/values-ar/strings.xml
@@ -64,6 +64,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"لم يتم العثور على طابعات"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"جارٍ طباعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"جارٍ إلغاء <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -82,6 +83,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"لا يوجد اتصال بالطابعة"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"غير معروف"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – غير متاحة"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"هل تريد استخدام <xliff:g id="SERVICE">%1$s</xliff:g>؟"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"من الممكن أن يمر المستند عبر خادم أو أكثر أثناء إرساله إلى الطابعة."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"أبيض وأسود"</item>
     <item msgid="2762241247228983754">"ملونة"</item>
diff --git a/packages/PrintSpooler/res/values-az-rAZ/strings.xml b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
index c102745..c8ca06c 100644
--- a/packages/PrintSpooler/res/values-az-rAZ/strings.xml
+++ b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Heç bir printer tapılmadı"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> çap edilir"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ləğv edilir"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printerə heç bir bağlantı yoxdur"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"naməlum"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>– əlçatmaz"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> xidmətindən istifadə edilsin?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Sənədiniz printerə qədər bir və ya daha çox server vasitəsilə keçə bilər."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Qara &amp; Ağ"</item>
     <item msgid="2762241247228983754">"Rəng"</item>
diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml
index c88d0d4..7129cc1 100644
--- a/packages/PrintSpooler/res/values-bg/strings.xml
+++ b/packages/PrintSpooler/res/values-bg/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Няма намерени принтери"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се отпечатва"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се анулира"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Няма връзка с принтера"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"няма данни"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – не е налице"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Да се използва ли „<xliff:g id="SERVICE">%1$s</xliff:g>“?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"По пътя към принтера документът ви може да премине през един или повече сървъри."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Черно-бяло"</item>
     <item msgid="2762241247228983754">"Цветно"</item>
diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
index 45f20a0..ae0b01c 100644
--- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml
+++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"কোনো মুদ্রক পাওয়া যায়নি"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> মুদ্রণ করা হচ্ছে"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> বাতিল করা হচ্ছে"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"মুদ্রকে কোনো সংযোগ নেই"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"অজানা"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – অনুপলব্ধ"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ব্যবহার করবেন?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"আপনার দস্তাবেজ মুদ্রকে যাওয়ার সময় এক বা একাধিক সার্ভারের মাধ্যমে পাস হতে পারে।"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"কালো এবং সাদা"</item>
     <item msgid="2762241247228983754">"রঙ"</item>
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
index 612be97..d221c6c 100644
--- a/packages/PrintSpooler/res/values-ca/strings.xml
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"No s\'ha trobat cap impressora"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"S\'està imprimint <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"S\'està cancel·lant <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No hi ha connexió amb la impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconegut"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vols fer servir <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"És possible que el document passi com a mínim per un servidor abans d\'imprimir-se."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Blanc i negre"</item>
     <item msgid="2762241247228983754">"Color"</item>
diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml
index 99ed75d..5396b3e 100644
--- a/packages/PrintSpooler/res/values-cs/strings.xml
+++ b/packages/PrintSpooler/res/values-cs/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nebyly nalezeny žádné tiskárny"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Tisk úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Rušení úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nelze se připojit k tiskárně"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"neznámé"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – není k dispozici"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Použít službu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument může cestou do tiskárny projít jedním i více servery."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Černobíle"</item>
     <item msgid="2762241247228983754">"Barevně"</item>
diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml
index 526e976..484d66f 100644
--- a/packages/PrintSpooler/res/values-da/strings.xml
+++ b/packages/PrintSpooler/res/values-da/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Der blev ikke fundet nogen printere"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> udskrives"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annulleres"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse til printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ukendt"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ikke tilgængelig"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vil du bruge <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dit dokument passerer muligvis gennem én eller flere servere på vej til printeren."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Sort/hvid"</item>
     <item msgid="2762241247228983754">"Farve"</item>
diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
index ef5e34c..c6323ef 100644
--- a/packages/PrintSpooler/res/values-de/strings.xml
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Keine Drucker gefunden"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird gedruckt..."</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird abgebrochen..."</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Keine Verbindung zum Drucker"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unbekannt"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nicht verfügbar"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> verwenden?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Ihr Dokument passiert bei der Übermittlung an den Drucker möglicherweise einen oder mehrere Server."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Schwarz-weiß"</item>
     <item msgid="2762241247228983754">"Farbe"</item>
diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml
index a4bb04c..85923b7 100644
--- a/packages/PrintSpooler/res/values-el/strings.xml
+++ b/packages/PrintSpooler/res/values-el/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Δεν βρέθηκαν εκτυπωτές"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Εκτύπωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ακύρωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Δεν υπάρχει σύνδεση με εκτυπωτή"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"άγνωστο"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – μη διαθέσιμο"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Να χρησιμοποιηθεί η υπηρεσία <xliff:g id="SERVICE">%1$s</xliff:g>;"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Το έγγραφό σας μπορεί να περάσει από έναν ή περισσότερους διακομιστές κατά τη μετάβαση στον εκτυπωτή."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Ασπρόμαυρο"</item>
     <item msgid="2762241247228983754">"Χρώμα"</item>
diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml
index 9f0d7e5..5ac14a3 100644
--- a/packages/PrintSpooler/res/values-en-rAU/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Black &amp; White"</item>
     <item msgid="2762241247228983754">"Colour"</item>
diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml
index 9f0d7e5..5ac14a3 100644
--- a/packages/PrintSpooler/res/values-en-rGB/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Black &amp; White"</item>
     <item msgid="2762241247228983754">"Colour"</item>
diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml
index 9f0d7e5..5ac14a3 100644
--- a/packages/PrintSpooler/res/values-en-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Black &amp; White"</item>
     <item msgid="2762241247228983754">"Colour"</item>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index ef0dbb1..1876ae1 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"No se encontraron impresoras"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora."</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"¿Deseas usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Es posible que el documento pase por uno o varios servidores antes de imprimirse."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Blanco y negro"</item>
     <item msgid="2762241247228983754">"Color"</item>
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
index 067c134..14ed0d8 100644
--- a/packages/PrintSpooler/res/values-es/strings.xml
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"No se encontraron impresoras"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – no disponible"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"¿Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Es posible que el documento pase por uno o varios servidores antes de imprimirse."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Blanco y negro"</item>
     <item msgid="2762241247228983754">"Color"</item>
diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml
index 0227131..c284332 100644
--- a/packages/PrintSpooler/res/values-et-rEE/strings.xml
+++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Printereid ei leitud"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> printimine"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> tühistamine"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printeriühendus puudub"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"teadmata"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – pole saadaval"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Kas soovite kasutada teenust <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Printerini jõudmiseks võib dokument läbida ühe või mitu serverit."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Mustvalge"</item>
     <item msgid="2762241247228983754">"Värv"</item>
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index 461a92f..eab7587 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Ez da inprimagailurik aurkitu"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> inprimatzen"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> bertan behera uzten"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Inprimagailua ez dago konektatuta"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ezezaguna"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: ez dago erabilgarri"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> erabili nahi duzu?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Baliteke dokumentuak zerbitzari batean edo gehiagotan zehar igarotzea inprimagailurako bidean."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Zuri-beltza"</item>
     <item msgid="2762241247228983754">"Koloretakoa"</item>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index 0e1629f..156eb47 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"هیچ چاپگری یافت نشد"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"در حال چاپ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"در حال لغو <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"اتصال با چاپگر برقرار نیست"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"نامعلوم"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - در دسترس نیست"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"از <xliff:g id="SERVICE">%1$s</xliff:g> استفاده شود؟"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ممکن است سندتان برای رسیدن به چاپگر از یک یا چند سرور عبور کند."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"سیاه و سفید"</item>
     <item msgid="2762241247228983754">"رنگی"</item>
diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml
index faf40e2..887d428 100644
--- a/packages/PrintSpooler/res/values-fi/strings.xml
+++ b/packages/PrintSpooler/res/values-fi/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Tulostimia ei löydy"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Tulostetaan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Peruutetaan työ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ei yhteyttä tulostimeen"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"tuntematon"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ei käytettävissä"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Käytetäänkö palvelua <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Asiakirja saattaa kulkea yhden tai useamman palvelimen kautta matkalla tulostimeen."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Mustavalkoinen"</item>
     <item msgid="2762241247228983754">"Väri"</item>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index f949bb7..a97b20a 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Aucune imprimante trouvée"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> en cours…"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> »…"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"inconnu"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — indisponible"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Utiliser <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Votre document peut passer par un ou plusieurs serveurs avant d\'arriver à l\'imprimante."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Noir et blanc"</item>
     <item msgid="2762241247228983754">"Couleur"</item>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
index 1f5c716..726915b 100644
--- a/packages/PrintSpooler/res/values-fr/strings.xml
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Aucune imprimante trouvée"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante."</string>
     <string name="reason_unknown" msgid="5507940196503246139">"inconnue"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponible"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Utiliser <xliff:g id="SERVICE">%1$s</xliff:g> ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Votre document peut passer par un ou plusieurs serveurs avant d\'être envoyé sur l\'imprimante."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Noir et blanc"</item>
     <item msgid="2762241247228983754">"Couleur"</item>
diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml
index 0d4b040..6a2d031 100644
--- a/packages/PrintSpooler/res/values-gl-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Non se atopou ningunha impresora"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Non hai conexión coa impresora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"descoñecido"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: non dispoñible"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Queres usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"É posible que o teu documento pase por un ou máis servidores antes de imprimirse."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Branco e negro"</item>
     <item msgid="2762241247228983754">"Cor"</item>
diff --git a/packages/PrintSpooler/res/values-gu-rIN/strings.xml b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
index 28ffc2a..3b3d2ed 100644
--- a/packages/PrintSpooler/res/values-gu-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"કોઈ પ્રિન્ટર મળ્યા નથી"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> છાપી રહ્યાં છે"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ને રદ કરી રહ્યું છે"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"પ્રિન્ટર માટે કોઈ કનેક્શન નથી"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"અજાણ્યું"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – અનુપલબ્ધ"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> નો ઉપયોગ કરીએ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"તમારો દસ્તાવેજ પ્રિન્ટર સુધીના તેના માર્ગમાં એક અથવા વધુ સર્વર્સથી પસાર થઈ શકે છે."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"શ્યામ અને શ્વેત"</item>
     <item msgid="2762241247228983754">"રંગ"</item>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index 1a0f7d1..162f65b 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"कोई प्रिंटर नहीं मिले"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> प्रिंट हो रहा है"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द हो रहा है"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटर के लिए कोई कनेक्शन नहीं"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – अनुपलब्ध"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> का उपयोग करें?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"प्रिंटर पर जाते समय आपका दस्तावेज़ एक या अधिक सर्वर से गुज़र सकता है."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"श्याम और श्वेत"</item>
     <item msgid="2762241247228983754">"रंग"</item>
diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml
index 3e38d65..9276300 100644
--- a/packages/PrintSpooler/res/values-hr/strings.xml
+++ b/packages/PrintSpooler/res/values-hr/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nije pronađen nijedan pisač"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Ispisivanje <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazivanje zadatka <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -76,6 +77,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze s pisačem"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – zadatak nije dostupan"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li upotrijebiti uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Na putu do pisača vaš dokument može proći kroz jedan ili više poslužitelja."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Crno-bijelo"</item>
     <item msgid="2762241247228983754">"U boji"</item>
diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml
index 2b24b1f..ca48f9a 100644
--- a/packages/PrintSpooler/res/values-hu/strings.xml
+++ b/packages/PrintSpooler/res/values-hu/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nem található nyomtató"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> nyomtatása"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> törlése"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nincs kapcsolat a nyomtatóval"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ismeretlen"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nem érhető el"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Használni szeretné a következő szolgáltatást: <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"A dokumentum áthaladhat egy vagy több szerveren, mielőtt a nyomtatóhoz érne."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Fekete-fehér"</item>
     <item msgid="2762241247228983754">"Szín"</item>
diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
index 56f94b4..a198277 100644
--- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml
+++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Տպիչներ չեն գտնվել"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Տպվում է՝ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ը չեղարկվում է"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Տպիչի հետ կապ չկա"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"անհայտ"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> տպիչն անհասանելի է"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Օգտագործե՞լ <xliff:g id="SERVICE">%1$s</xliff:g>-ը:"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Հնարավոր է՝ փաստաթուղթը մի քանի սերվերներով անցնի մինչ տպվելը:"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Սև ու սպիտակ"</item>
     <item msgid="2762241247228983754">"Գույնը"</item>
diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml
index d09fcfe..5050700 100644
--- a/packages/PrintSpooler/res/values-in/strings.xml
+++ b/packages/PrintSpooler/res/values-in/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Tidak ditemukan printer"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Tidak ada sambungan ke printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"tak diketahui"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gunakan <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumen Anda dapat melewati satu atau beberapa server saat menuju printer."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Hitam &amp; Putih"</item>
     <item msgid="2762241247228983754">"Warna"</item>
diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml
index bf13ebf..33f10f5 100644
--- a/packages/PrintSpooler/res/values-is-rIS/strings.xml
+++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Engir prentarar fundust"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Prentar <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Hættir við <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Engin tenging við prentara"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"óþekkt"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ekki í boði"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Nota <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Skjalið gæti þurft að fara í gegnum einn eða fleiri þjóna á leið sinni til prentarans."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Svarthvítt"</item>
     <item msgid="2762241247228983754">"Í lit"</item>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
index b052341..f7c6eff 100644
--- a/packages/PrintSpooler/res/values-it/strings.xml
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nessuna stampante trovata"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Stampa di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annullamento di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nessun collegamento alla stampante"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"sconosciuto"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - non disponibile"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Utilizzare <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Il tuo documento potrebbe passare da uno o più server per raggiungere la stampante."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Bianco e nero"</item>
     <item msgid="2762241247228983754">"A colori"</item>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index bb1967d..545ba88 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"לא נמצאו מדפסות"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"מדפיס את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"מבטל את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"אין חיבור למדפסת"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"לא ידוע"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – לא זמינה"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"האם להשתמש ב-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ייתכן שהמסמך שלך יעבור בשרת אחד או יותר בדרכו למדפסת."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"שחור ולבן"</item>
     <item msgid="2762241247228983754">"צבע"</item>
diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml
index 8ef7517..e292013 100644
--- a/packages/PrintSpooler/res/values-ja/strings.xml
+++ b/packages/PrintSpooler/res/values-ja/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"プリンタが見つかりません"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>を印刷しています"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>をキャンセルしています"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"プリンタに接続されていません"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>–使用不可"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>を利用しますか?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ドキュメントは1つ以上のサーバーを経由してプリンタに送信されることがあります。"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"モノクロ"</item>
     <item msgid="2762241247228983754">"カラー"</item>
diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
index b65d013..db71506 100644
--- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml
+++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"პრინტერები ვერ მოიძებნა"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"იბეჭდება <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"მიმდინარეობს <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ის გაუქმება"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"პრინტერთან კავშირი არ არის"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"უცნობი"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – მიუწვდომელია"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"გსურთ, გამოიყენოთ <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"პრინტერამდე გზად დოკუმენტმა შეიძლება ერთი ან მეტი სერვერი გაიაროს."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"შავ-თეთრი"</item>
     <item msgid="2762241247228983754">"ფერი"</item>
diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
index ef914f0c..de2115a 100644
--- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
+++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
@@ -60,6 +60,8 @@
     </plurals>
     <string name="choose_print_service" msgid="3740309762324459694">"Принтер қызметін таңдау"</string>
     <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтерлерді іздеу"</string>
+    <!-- no translation found for print_no_print_services (8561247706423327966) -->
+    <skip />
     <string name="print_no_printers" msgid="4869403323900054866">"Ешқандай принтер табылмады"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> басып шығарылуда"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> жұмысын тоқтатуда"</string>
@@ -74,6 +76,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтермен байланыс жоқ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"белгісіз"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – қол жетімсіз"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> қолданылсын ба?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Құжат принтерге жеткенше бір немесе бірнеше серверден өтуі мүмкін."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Қара &amp; Ақ"</item>
     <item msgid="2762241247228983754">"Түс"</item>
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
index 3aac97f..c91e6ae 100644
--- a/packages/PrintSpooler/res/values-km-rKH/strings.xml
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"រក​មិន​ឃើញ​ម៉ាស៊ីន​បោះពុម្ព"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"កំពុង​​បោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ការ​បោះបង់ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មាន​​​ការ​ភ្ជាប់​ទៅ​ម៉ាស៊ីន​បោះពុម្ព​"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"មិន​ស្គាល់"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – មិន​អាច​ប្រើ​បាន"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"ប្រើ <xliff:g id="SERVICE">%1$s</xliff:g> ឬ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ឯកសាររបស់អ្នកអាចនឹងឆ្លងកាត់ម៉ាស៊ីនមេមួយ ឬច្រើននៅពេលដែលវាធ្វើដំណើរទៅកាន់ម៉ាស៊ីនបោះពុម្ព។"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"ស &amp; ខ្មៅ"</item>
     <item msgid="2762241247228983754">"ពណ៌"</item>
diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
index 72e0bac..86dc11f 100644
--- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"ಯಾವುದೇ ಮುದ್ರಕಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ಮುದ್ರಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ರದ್ದು ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ಮುದ್ರಕಕ್ಕೆ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ಅಜ್ಞಾತ"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ಲಭ್ಯವಿಲ್ಲ"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ಬಳಸುವುದೇ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ನಿಮ್ಮ ಡಾಕ್ಯುಮೆಂಟ್‌ ಪ್ರಿಂಟರ್‌ಗೆ ಹೋಗುವ ಸಂದರ್ಭದಲ್ಲಿ ಒಂದು ಅಥವಾ ಅದಕ್ಕಿಂತ ಹೆಚ್ಚು ಸರ್ವರ್‌ಗಳ ಮೂಲಕ ಹಾದು ಹೋಗಬಹುದು."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"ಕಪ್ಪು &amp; ಬಿಳುಪು"</item>
     <item msgid="2762241247228983754">"ಬಣ್ಣ"</item>
diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml
index 0d9a4dd..4450bca 100644
--- a/packages/PrintSpooler/res/values-ko/strings.xml
+++ b/packages/PrintSpooler/res/values-ko/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"프린터 없음"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 인쇄 중"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 취소 중"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"프린터와 연결되지 않음"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"알 수 없음"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 사용할 수 없음"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>을(를) 사용할까요?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"문서가 프린터로 전송되는 중에 하나 이상의 서버를 통과할 수 있습니다."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"흑백"</item>
     <item msgid="2762241247228983754">"컬러"</item>
diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
index 7f6eb10..b4bdc57 100644
--- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml
+++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Принтерлер табылган жок"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> басылууда"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> токтотулууда"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер менен байланыш жок"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"белгисиз"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – жеткиликтүү эмес"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> колдонулсунбу?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Принтерге жеткиче документиңиз бир же андан көп серверлерден өтүшү мүмкүн."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Кара-ак"</item>
     <item msgid="2762241247228983754">"Түстүү"</item>
diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
index 7e65b72..500f01c 100644
--- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml
+++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"ບໍ່ພົບເຄື່ອງພິມ"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"ກຳລັງພິມ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ກຳລັງຍົກເລີກ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ບໍ່ມີການເຊື່ອມຕໍ່ຫາເຄື່ອງພິມ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ບໍ່ຮູ້ຈັກ"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - ບໍ່ມີຢູ່"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"ໃຊ້ <xliff:g id="SERVICE">%1$s</xliff:g> ບໍ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ເອກະສານຂອງທ່ານອາດເດີນທາງຜ່ານໜຶ່ງ ຫຼື ຫຼາຍເຊີບເວີ ເພື່ອໄປຮອດເຄື່ອງພິມ."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"ຂາວດຳ"</item>
     <item msgid="2762241247228983754">"ສີ"</item>
diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml
index a3129cc..ad59182 100644
--- a/packages/PrintSpooler/res/values-lt/strings.xml
+++ b/packages/PrintSpooler/res/values-lt/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nerasta spausdintuvų"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Spausdinama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Atšaukiama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nėra ryšio su spausdintuvu"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nežinoma"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ – nepasiekiama"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Naudoti „<xliff:g id="SERVICE">%1$s</xliff:g>“?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Kai dokumentas siunčiamas į spausdintuvą, jis gali būti perduodamas per vieną ar daugiau serverių."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Nespalvotas"</item>
     <item msgid="2762241247228983754">"Spalva"</item>
diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml
index daadf99..3b30d04 100644
--- a/packages/PrintSpooler/res/values-lv/strings.xml
+++ b/packages/PrintSpooler/res/values-lv/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Netika atrasts neviens printeris."</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Notiek darba <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> drukāšana…"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Pārtrauc drukas darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string>
@@ -76,6 +77,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nav savienojuma ar printeri"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nezināms"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — nav pieejams"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vai izmantot pakalpojumu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokuments, iespējams, tiek pārsūtīts caur vienu vai vairākiem serveriem, līdz tas nonāk līdz printerim."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Melnbalts"</item>
     <item msgid="2762241247228983754">"Krāsa"</item>
diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
index 3ebc1c9..42548fc 100644
--- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml
+++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Не се пронајдени печатачи"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> се печати"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> се откажува"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Нема поврзување со печатач"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - недостапен"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Користи <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"На пат до печатачот, документот може да помине преку еден или повеќе сервери."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Црно-бела"</item>
     <item msgid="2762241247228983754">"Во боја"</item>
diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
index 63b4060..4e5a99c 100644
--- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"പ്രിന്ററുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> പ്രിന്റുചെയ്യുന്നു"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> റദ്ദാക്കുന്നു"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"പ്രിന്ററിൽ കണക്ഷനൊന്നുമില്ല"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"അജ്ഞാതം"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ലഭ്യമല്ല"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ഉപയോഗിക്കണോ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"നിങ്ങളുടെ പ്രമാണം പ്രിന്ററിലേക്ക് പോകുന്നതിനിടെ അത് ഒന്നോ അതിലധികമോ സെർവറുകളിലൂടെ കടന്നുപോകാനിടയുണ്ട്."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"കറുപ്പ് &amp; വെള്ള"</item>
     <item msgid="2762241247228983754">"നിറം"</item>
diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
index a8628c9..0f49671 100644
--- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml
+++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Принтер олдсонгүй"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Хэвлэж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Цуцлаж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер холбогдоогүй байна"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"тодорхойгүй"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ашиглах боломжгүй"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>-г ашиглах уу?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Таны документ хэвлэгчид иртэл нэг эсвэл хэд хэдэн серверээр дамжина."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Хар &amp; Цагаан"</item>
     <item msgid="2762241247228983754">"Өнгө"</item>
diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
index c08e440..53225ee 100644
--- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"कोणतेही प्रिंटर आढळले नाही"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> मुद्रण करीत आहे"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द करीत आहे"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटरवर कोणतेही कनेक्‍शन नाही"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – अनुपलब्‍ध"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> वापरायची?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"आपला दस्तऐवज प्रिंटरपर्यंत पोहचण्‍यापूर्वी एक किंवा अधिक सर्व्हरद्वारे जाऊ शकतो."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"कृष्‍ण धवल"</item>
     <item msgid="2762241247228983754">"रंग"</item>
diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
index 4ed1019..a15587b 100644
--- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml
+++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Tiada pencetak ditemui"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Tiada sambungan ke pencetak"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"tidak diketahui"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gunakan <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumen anda mungkin melalui satu atau beberapa pelayan dalam perjalanan ke pencetak."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Hitam &amp; Putih"</item>
     <item msgid="2762241247228983754">"Warna"</item>
diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml
index 0a65a11..10dc93a 100644
--- a/packages/PrintSpooler/res/values-my-rMM/strings.xml
+++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"စာထုတ်စက် တစ်ခုမှ မတွေ့ရှိပါ"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ကို စာထုတ်နေပါသည်"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ကို ပယ်ဖျက်နေပါသည်"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"စာထုတ်စက်နဲ့ ဆက်သွယ်ထားမှု မရှိပါ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"အကြောင်းအရာ မသိရှိ"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – မတွေ့ရှိပါ"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ကိုသုံးမလား။"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"သင်၏ စာရွက်စာတမ်းများသည် ပရင်တာထံသို့ သွားစဉ် ဆာဗာ တစ်ခု သို့မဟုတ် ပိုများပြီး ဖြတ်ကျော်နိုင်ရသည်။"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"အဖြူ အမည်း"</item>
     <item msgid="2762241247228983754">"ရောင်စုံ"</item>
diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml
index 7c74b39..8cbcee7 100644
--- a/packages/PrintSpooler/res/values-nb/strings.xml
+++ b/packages/PrintSpooler/res/values-nb/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Fant ingen skrivere"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse med skriveren"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ukjent"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – utilgjengelig"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vil du bruke <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumentet ditt kan gå via flere tjenere før det når skriveren."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Svart og hvitt"</item>
     <item msgid="2762241247228983754">"Farge"</item>
diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
index 42cd98b..ad9b4e3 100644
--- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml
+++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"कुनै प्रिन्टरहरू भेटाइएन"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"प्रिन्ट गरिँदै <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"रद्द गरिँदै <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिन्टरमा कुनै जडान छैन"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - अनुपलब्ध"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्ने हो?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"तपाईँको कागजात प्रिन्टरमा जाँदा यसको मार्गमा एक वा धेरै सर्भरहरू पार हुनसक्छन्।"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"कालो &amp; सेतो"</item>
     <item msgid="2762241247228983754">"रङ्ग"</item>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
index 4855e31..bb8391e 100644
--- a/packages/PrintSpooler/res/values-nl/strings.xml
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Geen printers gevonden"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> afdrukken"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annuleren"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niet beschikbaar"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> gebruiken?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Je document kan via een of meer servers naar de printer worden verzonden."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Zwart-wit"</item>
     <item msgid="2762241247228983754">"Kleur"</item>
diff --git a/packages/PrintSpooler/res/values-pa-rIN/strings.xml b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
index 912cf4a..aede004 100644
--- a/packages/PrintSpooler/res/values-pa-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"ਕੋਈ ਪ੍ਰਿੰਟਰ ਨਹੀਂ ਮਿਲੇ"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ਨੂੰ ਪ੍ਰਿੰਟ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ਨੂੰ ਰੱਦ ਕਰ ਰਿਹਾ ਹੈ"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ਪ੍ਰਿੰਟਰ ਲਈ ਕੋਈ ਕਨੈਕਸ਼ਨ ਨਹੀਂ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ਅਗਿਆਤ"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ਅਣਉਪਲਬਧ"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"ਕੀ <xliff:g id="SERVICE">%1$s</xliff:g> ਵਰਤਣੀ ਹੈ?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ਤੁਹਾਡਾ ਦਸਤਾਵੇਜ਼ ਪ੍ਰਿੰਟਰ ਵਿੱਚ ਜਾਣ ਲਈ ਇੱਕ ਜਾਂ ਦੋ ਸਰਵਰਾਂ ਵਿੱਚੋਂ ਲੰਘਦਾ ਹੈ।"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"ਕਾਲਾ &amp; ਚਿੱਟਾ"</item>
     <item msgid="2762241247228983754">"ਰੰਗ"</item>
diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml
index 055fb5f..4e20eed 100644
--- a/packages/PrintSpooler/res/values-pl/strings.xml
+++ b/packages/PrintSpooler/res/values-pl/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nie znaleziono drukarek"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Drukowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Anulowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Brak połączenia z drukarką"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"brak informacji"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niedostępne"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Użyć usługi <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Zanim dokument dotrze do drukarki, może przejść przez jeden lub kilka serwerów."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Czarno-białe"</item>
     <item msgid="2762241247228983754">"Kolor"</item>
diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
index 9e38506..7ab0f0a 100644
--- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Seu documento pode passar por um ou mais servidores até chegar à impressora."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Preto e branco"</item>
     <item msgid="2762241247228983754">"Cor"</item>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index 73fabab..583052a 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"A imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A cancelar <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem ligação à impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponível"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Pretende utilizar o <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"O seu documento pode passar por um ou mais servidores no respetivo caminho para a impressora."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Preto e branco"</item>
     <item msgid="2762241247228983754">"Cor"</item>
diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml
index 9e38506..7ab0f0a 100644
--- a/packages/PrintSpooler/res/values-pt/strings.xml
+++ b/packages/PrintSpooler/res/values-pt/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Seu documento pode passar por um ou mais servidores até chegar à impressora."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Preto e branco"</item>
     <item msgid="2762241247228983754">"Cor"</item>
diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml
index 3ff1045..2769aae 100644
--- a/packages/PrintSpooler/res/values-ro/strings.xml
+++ b/packages/PrintSpooler/res/values-ro/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nu au fost găsite imprimante"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Se printează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Se anulează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -76,6 +77,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nu există conexiune la o imprimantă"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"necunoscut"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - indisponibil"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Folosiți <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Documentul poate trece prin unul sau mai multe servere pe calea spre imprimantă."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Alb-negru"</item>
     <item msgid="2762241247228983754">"Color"</item>
diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml
index a4e12fe..c3cfac0 100644
--- a/packages/PrintSpooler/res/values-ru/strings.xml
+++ b/packages/PrintSpooler/res/values-ru/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Ничего не найдено"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Печать задания \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\"…"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отмена задания <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Нет связи с принтером"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"неизвестно"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступен"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Использовать <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ может пересылаться на принтер через несколько серверов."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Черно-белая"</item>
     <item msgid="2762241247228983754">"Цветная"</item>
diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml
index e8052d6..0e20705 100644
--- a/packages/PrintSpooler/res/values-si-rLK/strings.xml
+++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"මුද්‍රණ යන්ත්‍ර සොයා නොගැනුණි"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> මුද්‍රණය වේ"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"අවලංගු කෙරේ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"මුද්‍රණ යන්ත්‍රය වෙත සම්බන්ධය නැත"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"නොදනී"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ලද නොහැක"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> භාවිත කරන්නද?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ඔබගේ ලේඛනය මුද්‍රණ යන්ත්‍රයට යන අතරතුර සේවාදායක එකක් හෝ කිහිපයක් හරහා යා හැක."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"කළු සහ සුදු"</item>
     <item msgid="2762241247228983754">"වර්ණය"</item>
diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml
index 3e82076..b8d2167 100644
--- a/packages/PrintSpooler/res/values-sk/strings.xml
+++ b/packages/PrintSpooler/res/values-sk/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nenašli sa žiadne tlačiarne"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Prebieha tlač úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prebieha zrušenie úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Žiadne pripojenie k tlačiarni"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"neznáme"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie je k dispozícii"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Použiť službu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Skôr ako sa váš dokument dostane do tlačiarne, môže prejsť jedným alebo viacerými servermi."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Čiernobiele"</item>
     <item msgid="2762241247228983754">"Farba"</item>
diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml
index 75c2abe..a320e79 100644
--- a/packages/PrintSpooler/res/values-sl/strings.xml
+++ b/packages/PrintSpooler/res/values-sl/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Tiskalnikov ni mogoče najti"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Tiskanje: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Preklic: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ni povezave s tiskalnikom"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"neznano"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ni na voljo"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite uporabiti storitev <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument gre lahko na poti do tiskalnika skozi enega ali več strežnikov."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Črno-belo"</item>
     <item msgid="2762241247228983754">"Barvno"</item>
diff --git a/packages/PrintSpooler/res/values-sq-rAL/strings.xml b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
index adbf700..177b282 100644
--- a/packages/PrintSpooler/res/values-sq-rAL/strings.xml
+++ b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Nuk u gjet asnjë printer"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Po printon <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Po anulon <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printeri nuk është i lidhur"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"e panjohur"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nuk mundësohet"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Përdor <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumenti mund të kalojë përmes një ose shumë serverëve deri te printeri."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Bardhezi"</item>
     <item msgid="2762241247228983754">"Ngjyra"</item>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index 58e9622..f686e6d 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -61,6 +61,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Није пронађен ниједан штампач"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Штампа се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отказује се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -76,6 +77,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Нема везе са штампачем"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступан"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Желите ли да користите <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ може да прође кроз један или више сервера на путу до штампача."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Црно-бело"</item>
     <item msgid="2762241247228983754">"Боја"</item>
diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml
index 0434903..6e176f03 100644
--- a/packages/PrintSpooler/res/values-sv/strings.xml
+++ b/packages/PrintSpooler/res/values-sv/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Det gick inte att hitta några skrivare"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen anslutning till skrivaren"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"okänt"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – inte tillgänglig"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vill du använda <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"På vägen till skrivaren kan dokumentet passera en eller flera servrar."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Svartvit"</item>
     <item msgid="2762241247228983754">"Färg"</item>
diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml
index 7c08316..8ce9190 100644
--- a/packages/PrintSpooler/res/values-sw/strings.xml
+++ b/packages/PrintSpooler/res/values-sw/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Hakuna printa zilizopatikana"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Inachapisha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Inaghairi <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Hakuna muunganisho kwa printa"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"haijulikani"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - haipatikani"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Ungependa kutumia <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Huenda hati yako ikapitia seva moja au zaidi kabla ya kufika kwenye printa."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Nyeusi na Nyeupe"</item>
     <item msgid="2762241247228983754">"Rangi"</item>
diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
index 4c9f135..486ddca 100644
--- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"பிரிண்டர்கள் எதுவுமில்லை"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ஐ அச்சிடுகிறது"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ஐ ரத்துசெய்கிறது"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"அச்சுப்பொறியுடன் இணைக்கப்படவில்லை"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"அறியப்படாதது"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – இல்லை"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ஐப் பயன்படுத்தவா?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"உங்கள் ஆவணம் பிரிண்டருக்குச் செல்லும் வழியில் ஒன்று அல்லது அதற்கு மேற்பட்ட சேவையகங்களைக் கடந்து செல்லக்கூடும்."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"கருப்பு &amp; வெள்ளை"</item>
     <item msgid="2762241247228983754">"வண்ணம்"</item>
diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml
index ffa994b..f0f7e07 100644
--- a/packages/PrintSpooler/res/values-te-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"ప్రింటర్‌లు కనుగొనబడలేదు"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను ముద్రిస్తోంది"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను రద్దు చేస్తోంది"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ప్రింటర్‌కు కనెక్షన్ లేదు"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"తెలియదు"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – అందుబాటులో లేదు"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ని ఉపయోగించాలా?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"మీ పత్రం ప్రింటర్‌కు వెళ్లే మార్గంలో ఒకటి లేదా అంతకంటే ఎక్కువ సర్వర్‌ల గుండా వెళ్లవచ్చు."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"నలుపు &amp; తెలుపు"</item>
     <item msgid="2762241247228983754">"రంగు"</item>
diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml
index 89e3082..d3ef7c6 100644
--- a/packages/PrintSpooler/res/values-th/strings.xml
+++ b/packages/PrintSpooler/res/values-th/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"ไม่พบเครื่องพิมพ์"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"กำลังพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"กำลังยกเลิก <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ไม่มีการเชื่อมต่อไปยังเครื่องพิมพ์"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ไม่ทราบ"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ไม่พร้อมใช้งาน"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"ใช้ <xliff:g id="SERVICE">%1$s</xliff:g> ไหม"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"เอกสารของคุณอาจต้องผ่านมากกว่าหนึ่งเซิร์ฟเวอร์ระหว่างส่งไปยังเครื่องพิมพ์"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"ขาวดำ"</item>
     <item msgid="2762241247228983754">"สี"</item>
diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml
index 445d8b0..061eeb9 100644
--- a/packages/PrintSpooler/res/values-tl/strings.xml
+++ b/packages/PrintSpooler/res/values-tl/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Walang mga printer na nakita"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Pini-print ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kinakansela ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Hindi nakakonekta sa printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"hindi alam"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – hindi available"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gusto mo bang gamitin ang <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Bago ma-print ang iyong dokumento, maaari itong dumaan sa isa o higit pang mga server."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Black &amp; White"</item>
     <item msgid="2762241247228983754">"Kulay"</item>
diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml
index 66d1e99..db203ae 100644
--- a/packages/PrintSpooler/res/values-tr/strings.xml
+++ b/packages/PrintSpooler/res/values-tr/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Yazıcı bulunamadı"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> yazdırılıyor"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> iptal ediliyor"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Yazıcı bağlantısı yok"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"bilinmiyor"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – kullanılamıyor"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> kullanılsın mı?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokümanınız yazıcıya giderken bir veya daha fazla sunucudan geçebilir."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Siyah Beyaz"</item>
     <item msgid="2762241247228983754">"Renkli"</item>
diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml
index fcd3fa6..09c0555 100644
--- a/packages/PrintSpooler/res/values-uk/strings.xml
+++ b/packages/PrintSpooler/res/values-uk/strings.xml
@@ -62,6 +62,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Принтери не знайдено"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" друкується"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" скасовується"</string>
@@ -78,6 +79,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Немає з’єднання з принтером"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"невідомо"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" не доступне"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Увімкнути службу <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Коли ви надсилаєте документ на принтер, він може проходити через декілька серверів."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Чорно-білий"</item>
     <item msgid="2762241247228983754">"Колір"</item>
diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
index 2c2c460..44ca82b 100644
--- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml
+++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"کوئی پرنٹرز نہيں ملے"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> پرنٹ کررہا ہے"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> کو منسوخ کر رہا ہے"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"پرنٹر کے ساتھ کوئی کنکشن نہیں ہے"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"نامعلوم"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – دستیاب نہیں ہے"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> استعمال کریں؟"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"آپ کی دستاویز پرنٹر تک جاتے ہوئے ممکن ہے ایک یا زیادہ سرورز سے گزرے۔"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"سیاہ و سفید"</item>
     <item msgid="2762241247228983754">"رنگ"</item>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index f88eca5..477e424 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Printerlar topilmadi"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Chop etilmoqda: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> bekor qilinmoqda"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printer ulanmagan"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"noma’lum"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – mavjud emas"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> xizmatidan foydalanilsinmi?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Hujjatingiz chop etilishidan oldin bir yoki bir necha serverlardan o‘tishi mumkin."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Oq &amp; qora"</item>
     <item msgid="2762241247228983754">"Rang"</item>
diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml
index 2d1e8fa..3428ec7 100644
--- a/packages/PrintSpooler/res/values-vi/strings.xml
+++ b/packages/PrintSpooler/res/values-vi/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"Không tìm thấy máy in"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"In <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Hủy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Không có kết nối nào với máy in"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"không xác định"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – không khả dụng"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Sử dụng <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Tài liệu của bạn có thể đi qua một hoặc nhiều máy chủ trên đường đến máy in."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Đen trắng"</item>
     <item msgid="2762241247228983754">"Màu"</item>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
index 553bc89..d1be250 100644
--- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"找不到打印机"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"正在打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"未与打印机建立连接"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"未知"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - 无法使用"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用<xliff:g id="SERVICE">%1$s</xliff:g>吗?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文档可能会通过一个或多个服务器发送至打印机。"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"黑白"</item>
     <item msgid="2762241247228983754">"彩色"</item>
diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
index 74b301f..bca0612 100644
--- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"找不到打印機"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與打印機連線"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用 <xliff:g id="SERVICE">%1$s</xliff:g> 嗎?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文件可能會通過一部或多部伺服器才傳送至打印機。"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"黑白"</item>
     <item msgid="2762241247228983754">"彩色"</item>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
index d91fe52..c345252 100644
--- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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>
     <string name="print_no_printers" msgid="4869403323900054866">"找不到印表機"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與印表機建立連線"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用「<xliff:g id="SERVICE">%1$s</xliff:g>」嗎?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文件可能會透過一或多個伺服器輾轉傳送至印表機。"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"黑白"</item>
     <item msgid="2762241247228983754">"彩色"</item>
diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml
index 6ef2499..7ba8950 100644
--- a/packages/PrintSpooler/res/values-zu/strings.xml
+++ b/packages/PrintSpooler/res/values-zu/strings.xml
@@ -60,6 +60,7 @@
     </plurals>
     <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">"Awekho amasevisi okuphrinta enikwe amandla"</string>
     <string name="print_no_printers" msgid="4869403323900054866">"Awekho amaphrinta atholiwe"</string>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Iphrinta i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ikhansela i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
@@ -74,6 +75,8 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Akukho ukuxhumana kuphrinta"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"akwaziwa"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"I-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ayitholakali"</string>
+    <string name="print_service_security_warning_title" msgid="2160752291246775320">"Sebenzisa i-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Idokhumenti yakho ingase idlule iseva eyodwa noma amaningi lapho iya kuphrinta."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Okumnyama nokumhlophe"</item>
     <item msgid="2762241247228983754">"Umbala"</item>
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index e92f74c..6d81788 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -49,6 +49,9 @@
     <!-- Label of the page selection widget. [CHAR LIMIT=20] -->
     <string name="label_pages">Pages</string>
 
+    <!-- Label of the destination widget. [CHAR LIMIT=20] -->
+    <string name="destination_default_text">Select a printer</string>
+
     <!-- Template for the all pages option in the page selection widget. [CHAR LIMIT=20] -->
     <string name="template_all_pages">All <xliff:g id="page_count" example="100">%1$s</xliff:g></string>
 
@@ -149,6 +152,9 @@
     <!-- Title for the prompt shown as a placeholder if no printers are found while not searching. [CHAR LIMIT=50] -->
     <string name="print_searching_for_printers">Searching for printers</string>
 
+    <!-- Title for the prompt shown as a placeholder if there are no print services. [CHAR LIMIT=50] -->
+    <string name="print_no_print_services">No print services enabled</string>
+
     <!-- Title for the prompt shown as a placeholder if there are no printers while searching. [CHAR LIMIT=50] -->
     <string name="print_no_printers">No printers found</string>
 
@@ -187,6 +193,18 @@
     <!-- Label for a printer that is not available. [CHAR LIMIT=25] -->
     <string name="printer_unavailable"><xliff:g id="print_job_name" example="Canon-123GHT">%1$s</xliff:g> &#8211; unavailable</string>
 
+    <!-- Title for a warning message about security implications of using a print service,
+         displayed as a dialog message when the user prints using a print service that has not been
+         used before. [CHAR LIMIT=NONE] -->
+    <string name="print_service_security_warning_title">Use
+         <xliff:g id="service" example="My Print Service">%1$s</xliff:g>?</string>
+
+    <!-- Summary for a warning message about security implications of using a print service,
+         displayed as a dialog message when the user prints using a print service that has not been
+         used before. [CHAR LIMIT=NONE] -->
+    <string name="print_service_security_warning_summary">Your document may pass through one or
+         more servers on its way to the printer.</string>
+
     <!-- Arrays -->
 
     <!-- Color mode labels. -->
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index bafccae..7adcfec 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -50,6 +50,7 @@
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.printspooler.R;
+import com.android.printspooler.util.ApprovedPrintServices;
 
 import libcore.io.IoUtils;
 
@@ -67,6 +68,7 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Service for exposing some of the {@link PrintSpooler} functionality to
@@ -136,10 +138,10 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        synchronized (mLock) {
-            String prefix = (args.length > 0) ? args[0] : "";
-            String tab = "  ";
+        String prefix = (args.length > 0) ? args[0] : "";
+        String tab = "  ";
 
+        synchronized (mLock) {
             pw.append(prefix).append("print jobs:").println();
             final int printJobCount = mPrintJobs.size();
             for (int i = 0; i < printJobCount; i++) {
@@ -160,6 +162,14 @@
                 }
             }
         }
+
+        pw.append(prefix).append("approved print services:").println();
+        Set<String> approvedPrintServices = (new ApprovedPrintServices(this)).getApprovedServices();
+        if (approvedPrintServices != null) {
+            for (String approvedService : approvedPrintServices) {
+                pw.append(prefix).append(tab).append(approvedService).println();
+            }
+        }
     }
 
     private void sendOnPrintJobQueued(PrintJobInfo printJob) {
@@ -1307,6 +1317,12 @@
             PrintSpoolerService.this.setPrintJobCancelling(printJobId, cancelling);
         }
 
+        @Override
+        public void removeApprovedPrintService(ComponentName serviceToRemove) {
+            (new ApprovedPrintServices(PrintSpoolerService.this))
+                    .removeApprovedService(serviceToRemove);
+        }
+
         public PrintSpoolerService getService() {
             return PrintSpoolerService.this;
         }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index e8a5e43..e758835 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -17,14 +17,21 @@
 package com.android.printspooler.ui;
 
 import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
 import android.app.Fragment;
 import android.app.FragmentTransaction;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
@@ -57,6 +64,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
@@ -81,6 +89,7 @@
 import com.android.printspooler.model.RemotePrintDocument.RemotePrintDocumentInfo;
 import com.android.printspooler.renderer.IPdfEditor;
 import com.android.printspooler.renderer.PdfManipulationService;
+import com.android.printspooler.util.ApprovedPrintServices;
 import com.android.printspooler.util.MediaSizeUtils;
 import com.android.printspooler.util.MediaSizeUtils.MediaSizeComparator;
 import com.android.printspooler.util.PageRangeUtils;
@@ -88,6 +97,7 @@
 import com.android.printspooler.widget.PrintContentView;
 import com.android.printspooler.widget.PrintContentView.OptionsStateChangeListener;
 import com.android.printspooler.widget.PrintContentView.OptionsStateController;
+
 import libcore.io.IoUtils;
 import libcore.io.Streams;
 
@@ -116,6 +126,8 @@
 
     private static final String FRAGMENT_TAG = "FRAGMENT_TAG";
 
+    private static final String HAS_PRINTED_PREF = "has_printed";
+
     private static final int ORIENTATION_PORTRAIT = 0;
     private static final int ORIENTATION_LANDSCAPE = 1;
 
@@ -178,6 +190,7 @@
 
     private Spinner mDestinationSpinner;
     private DestinationAdapter mDestinationSpinnerAdapter;
+    private boolean mShowDestinationPrompt;
 
     private Spinner mMediaSizeSpinner;
     private ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter;
@@ -231,7 +244,9 @@
             throw new IllegalArgumentException(PrintManager.EXTRA_PRINT_JOB
                     + " cannot be null");
         }
-        mPrintJob.setAttributes(new PrintAttributes.Builder().build());
+        if (mPrintJob.getAttributes() == null) {
+            mPrintJob.setAttributes(new PrintAttributes.Builder().build());
+        }
 
         final IBinder adapter = extras.getBinder(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER);
         if (adapter == null) {
@@ -655,9 +670,11 @@
             }
         }
 
-        PrinterId printerId = mCurrentPrinter.getId();
-        final int index = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
-        mDestinationSpinner.setSelection(index);
+        if (mCurrentPrinter != null) {
+            PrinterId printerId = mCurrentPrinter.getId();
+            final int index = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
+            mDestinationSpinner.setSelection(index);
+        }
     }
 
     private void startAdvancedPrintOptionsActivity(PrinterInfo printer) {
@@ -1080,6 +1097,7 @@
 
         updateOptionsUi();
         addCurrentPrinterToHistory();
+        setUserPrinted();
 
         PageRange[] selectedPages = computeSelectedPages();
         if (!Arrays.equals(mSelectedPages, selectedPages)) {
@@ -1182,6 +1200,129 @@
         // Print button
         mPrintButton = (ImageView) findViewById(R.id.print_button);
         mPrintButton.setOnClickListener(clickListener);
+
+        // Special prompt instead of destination spinner for the first time the user printed
+        if (!hasUserEverPrinted()) {
+            mShowDestinationPrompt = true;
+
+            mSummaryCopies.setEnabled(false);
+            mSummaryPaperSize.setEnabled(false);
+
+            mDestinationSpinner.setOnTouchListener(new View.OnTouchListener() {
+                @Override
+                public boolean onTouch(View v, MotionEvent event) {
+                    mShowDestinationPrompt = false;
+                    mSummaryCopies.setEnabled(true);
+                    mSummaryPaperSize.setEnabled(true);
+                    updateOptionsUi();
+
+                    mDestinationSpinner.setOnTouchListener(null);
+                    mDestinationSpinnerAdapter.notifyDataSetChanged();
+
+                    return false;
+                }
+            });
+        }
+    }
+
+    /**
+     * A dialog that asks the user to approve a {@link PrintService}. This dialog is automatically
+     * dismissed if the same {@link PrintService} gets approved by another
+     * {@link PrintServiceApprovalDialog}.
+     */
+    private static final class PrintServiceApprovalDialog extends DialogFragment
+            implements OnSharedPreferenceChangeListener {
+        private static final String PRINTSERVICE_KEY = "PRINTSERVICE";
+        private ApprovedPrintServices mApprovedServices;
+
+        /**
+         * Create a new {@link PrintServiceApprovalDialog} that ask the user to approve a
+         * {@link PrintService}.
+         *
+         * @param printService The {@link ComponentName} of the service to approve
+         * @return A new {@link PrintServiceApprovalDialog} that might approve the service
+         */
+        static PrintServiceApprovalDialog newInstance(ComponentName printService) {
+            PrintServiceApprovalDialog dialog = new PrintServiceApprovalDialog();
+
+            Bundle args = new Bundle();
+            args.putParcelable(PRINTSERVICE_KEY, printService);
+            dialog.setArguments(args);
+
+            return dialog;
+        }
+
+        @Override
+        public void onStop() {
+            super.onStop();
+
+            mApprovedServices.unregisterChangeListener(this);
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+
+            ComponentName printService = getArguments().getParcelable(PRINTSERVICE_KEY);
+            synchronized (ApprovedPrintServices.sLock) {
+                if (mApprovedServices.isApprovedService(printService)) {
+                    dismiss();
+                } else {
+                    mApprovedServices.registerChangeListenerLocked(this);
+                }
+            }
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            super.onCreateDialog(savedInstanceState);
+
+            mApprovedServices = new ApprovedPrintServices(getActivity());
+
+            PackageManager packageManager = getActivity().getPackageManager();
+            CharSequence serviceLabel;
+            try {
+                ComponentName printService = getArguments().getParcelable(PRINTSERVICE_KEY);
+
+                serviceLabel = packageManager.getApplicationInfo(printService.getPackageName(), 0)
+                        .loadLabel(packageManager);
+            } catch (NameNotFoundException e) {
+                serviceLabel = null;
+            }
+
+            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+            builder.setTitle(getString(R.string.print_service_security_warning_title,
+                    serviceLabel))
+                    .setMessage(getString(R.string.print_service_security_warning_summary,
+                            serviceLabel))
+                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int id) {
+                            ComponentName printService =
+                                    getArguments().getParcelable(PRINTSERVICE_KEY);
+                            // Prevent onSharedPreferenceChanged from getting triggered
+                            mApprovedServices
+                                    .unregisterChangeListener(PrintServiceApprovalDialog.this);
+
+                            mApprovedServices.addApprovedService(printService);
+                            ((PrintActivity) getActivity()).confirmPrint();
+                        }
+                    })
+                    .setNegativeButton(android.R.string.cancel, null);
+
+            return builder.create();
+        }
+
+        @Override
+        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+            ComponentName printService = getArguments().getParcelable(PRINTSERVICE_KEY);
+
+            synchronized (ApprovedPrintServices.sLock) {
+                if (mApprovedServices.isApprovedService(printService)) {
+                    dismiss();
+                }
+            }
+        }
     }
 
     private final class MyClickListener implements OnClickListener {
@@ -1189,7 +1330,20 @@
         public void onClick(View view) {
             if (view == mPrintButton) {
                 if (mCurrentPrinter != null) {
-                    confirmPrint();
+                    if (mDestinationSpinnerAdapter.getPdfPrinter() == mCurrentPrinter) {
+                        confirmPrint();
+                    } else {
+                        ApprovedPrintServices approvedServices =
+                                new ApprovedPrintServices(PrintActivity.this);
+
+                        ComponentName printService = mCurrentPrinter.getId().getServiceName();
+                        if (approvedServices.isApprovedService(printService)) {
+                            confirmPrint();
+                        } else {
+                            PrintServiceApprovalDialog.newInstance(printService)
+                                    .show(getFragmentManager(), "approve");
+                        }
+                    }
                 } else {
                     cancelPrint();
                 }
@@ -1206,6 +1360,22 @@
                 && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
     }
 
+    /**
+     * Disable all options UI elements, beside the {@link #mDestinationSpinner}
+     */
+    private void disableOptionsUi() {
+        mCopiesEditText.setEnabled(false);
+        mCopiesEditText.setFocusable(false);
+        mMediaSizeSpinner.setEnabled(false);
+        mColorModeSpinner.setEnabled(false);
+        mDuplexModeSpinner.setEnabled(false);
+        mOrientationSpinner.setEnabled(false);
+        mRangeOptionsSpinner.setEnabled(false);
+        mPageRangeEditText.setEnabled(false);
+        mPrintButton.setVisibility(View.GONE);
+        mMoreOptionsButton.setEnabled(false);
+    }
+
     void updateOptionsUi() {
         // Always update the summary.
         updateSummary();
@@ -1220,32 +1390,14 @@
             if (mState != STATE_PRINTER_UNAVAILABLE) {
                 mDestinationSpinner.setEnabled(false);
             }
-            mCopiesEditText.setEnabled(false);
-            mCopiesEditText.setFocusable(false);
-            mMediaSizeSpinner.setEnabled(false);
-            mColorModeSpinner.setEnabled(false);
-            mDuplexModeSpinner.setEnabled(false);
-            mOrientationSpinner.setEnabled(false);
-            mRangeOptionsSpinner.setEnabled(false);
-            mPageRangeEditText.setEnabled(false);
-            mPrintButton.setVisibility(View.GONE);
-            mMoreOptionsButton.setEnabled(false);
+            disableOptionsUi();
             return;
         }
 
         // If no current printer, or it has no capabilities, or it is not
         // available, we disable all print options except the destination.
         if (mCurrentPrinter == null || !canPrint(mCurrentPrinter)) {
-            mCopiesEditText.setEnabled(false);
-            mCopiesEditText.setFocusable(false);
-            mMediaSizeSpinner.setEnabled(false);
-            mColorModeSpinner.setEnabled(false);
-            mDuplexModeSpinner.setEnabled(false);
-            mOrientationSpinner.setEnabled(false);
-            mRangeOptionsSpinner.setEnabled(false);
-            mPageRangeEditText.setEnabled(false);
-            mPrintButton.setVisibility(View.GONE);
-            mMoreOptionsButton.setEnabled(false);
+            disableOptionsUi();
             return;
         }
 
@@ -1553,6 +1705,10 @@
             mCopiesEditText.setText(MIN_COPIES_STRING);
             mCopiesEditText.requestFocus();
         }
+
+        if (mShowDestinationPrompt) {
+            disableOptionsUi();
+        }
     }
 
     private void updateSummary() {
@@ -1854,6 +2010,32 @@
         }
     }
 
+
+    /**
+     * Check if the user has ever printed a document
+     *
+     * @return true iff the user has ever printed a document
+     */
+    private boolean hasUserEverPrinted() {
+        SharedPreferences preferences = getSharedPreferences(HAS_PRINTED_PREF, MODE_PRIVATE);
+
+        return preferences.getBoolean(HAS_PRINTED_PREF, false);
+    }
+
+    /**
+     * Remember that the user printed a document
+     */
+    private void setUserPrinted() {
+        SharedPreferences preferences = getSharedPreferences(HAS_PRINTED_PREF, MODE_PRIVATE);
+
+        if (!preferences.getBoolean(HAS_PRINTED_PREF, false)) {
+            SharedPreferences.Editor edit = preferences.edit();
+
+            edit.putBoolean(HAS_PRINTED_PREF, true);
+            edit.apply();
+        }
+    }
+
     private final class DestinationAdapter extends BaseAdapter
             implements PrinterRegistry.OnPrintersChangeListener {
         private final List<PrinterHolder> mPrinterHolders = new ArrayList<>();
@@ -1862,6 +2044,11 @@
 
         private boolean mHistoricalPrintersLoaded;
 
+        /**
+         * Has the {@link #mDestinationSpinner} ever used a view from printer_dropdown_prompt
+         */
+        private boolean hadPromptView;
+
         public DestinationAdapter() {
             mHistoricalPrintersLoaded = mPrinterRegistry.areHistoricalPrintersLoaded();
             if (mHistoricalPrintersLoaded) {
@@ -1972,9 +2159,20 @@
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = getLayoutInflater().inflate(
-                        R.layout.printer_dropdown_item, parent, false);
+            if (mShowDestinationPrompt) {
+                if (convertView == null) {
+                    convertView = getLayoutInflater().inflate(
+                            R.layout.printer_dropdown_prompt, parent, false);
+                    hadPromptView = true;
+                }
+
+                return convertView;
+            } else {
+                // We don't know if we got an recyled printer_dropdown_prompt, hence do not use it
+                if (hadPromptView || convertView == null) {
+                    convertView = getLayoutInflater().inflate(
+                            R.layout.printer_dropdown_item, parent, false);
+                }
             }
 
             CharSequence title = null;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
index 3905bada..f4c15bd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
@@ -84,6 +84,11 @@
 
     private static final String EXTRA_PRINTER_ID = "EXTRA_PRINTER_ID";
 
+    /**
+     * If there are any enabled print services
+     */
+    private boolean mHasEnabledPrintServices;
+
     private final ArrayList<PrintServiceInfo> mAddPrinterServices =
             new ArrayList<>();
 
@@ -175,10 +180,6 @@
             }
         });
 
-        if (mAddPrinterServices.isEmpty()) {
-            menu.removeItem(R.id.action_add_printer);
-        }
-
         return true;
     }
 
@@ -230,6 +231,7 @@
     public void onResume() {
         super.onResume();
         updateServicesWithAddPrinterActivity();
+        updateEmptyView((DestinationAdapter)mListView.getAdapter());
         invalidateOptionsMenu();
     }
 
@@ -258,6 +260,7 @@
     }
 
     private void updateServicesWithAddPrinterActivity() {
+        mHasEnabledPrintServices = true;
         mAddPrinterServices.clear();
 
         // Get all enabled print services.
@@ -266,6 +269,7 @@
 
         // No enabled print services - done.
         if (enabledServices.isEmpty()) {
+            mHasEnabledPrintServices = false;
             return;
         }
 
@@ -324,7 +328,10 @@
         }
         TextView titleView = (TextView) findViewById(R.id.title);
         View progressBar = findViewById(R.id.progress_bar);
-        if (adapter.getUnfilteredCount() <= 0) {
+        if (!mHasEnabledPrintServices) {
+            titleView.setText(R.string.print_no_print_services);
+            progressBar.setVisibility(View.GONE);
+        } else if (adapter.getUnfilteredCount() <= 0) {
             titleView.setText(R.string.print_searching_for_printers);
             progressBar.setVisibility(View.VISIBLE);
         } else {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/util/ApprovedPrintServices.java b/packages/PrintSpooler/src/com/android/printspooler/util/ApprovedPrintServices.java
new file mode 100644
index 0000000..dd10567
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/util/ApprovedPrintServices.java
@@ -0,0 +1,156 @@
+/*
+ * 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.printspooler.util;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.printservice.PrintService;
+import android.util.ArraySet;
+
+import java.util.Set;
+
+/**
+ * Manage approved print services. These services are stored in the shared preferences.
+ */
+public class ApprovedPrintServices {
+    /**
+     * Used for locking accesses to the approved services.
+     */
+    static final public Object sLock = new Object();
+
+    private static final String APPROVED_SERVICES_PREFERENCE = "PRINT_SPOOLER_APPROVED_SERVICES";
+    private final SharedPreferences mPreferences;
+
+    /**
+     * Create a new {@link ApprovedPrintServices}
+     *
+     * @param owner The {@link Context} using this object.
+     */
+    public ApprovedPrintServices(Context owner) {
+        mPreferences = owner.getSharedPreferences(APPROVED_SERVICES_PREFERENCE,
+                Context.MODE_PRIVATE);
+    }
+
+    /**
+     * Get {@link Set} of approved services.
+     *
+     * @return A {@link Set} containing all currently approved services.
+     */
+    public Set<String> getApprovedServices() {
+        return mPreferences.getStringSet(APPROVED_SERVICES_PREFERENCE, null);
+    }
+
+    /**
+     * Check if a {@link PrintService} is approved.
+     *
+     * This function does not acquire the {@link #sLock}.
+     *
+     * @param service The {@link ComponentName} of the {@link PrintService} that might be approved
+     * @return true iff the service is currently approved
+     */
+    public boolean isApprovedService(ComponentName service) {
+        final Set<String> approvedServices = getApprovedServices();
+
+        if (approvedServices != null) {
+            final String flattenedString = service.flattenToShortString();
+
+            for (String approvedService : approvedServices) {
+                if (approvedService.equals(flattenedString)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Add a {@link PrintService} to the list of approved print services.
+     *
+     * @param serviceToAdd The {@link ComponentName} of the {@link PrintService} to be approved.
+     */
+    public void addApprovedService(ComponentName serviceToAdd) {
+        synchronized (sLock) {
+            Set<String> oldApprovedServices =
+                    mPreferences.getStringSet(APPROVED_SERVICES_PREFERENCE, null);
+
+            Set<String> newApprovedServices;
+            if (oldApprovedServices == null) {
+                newApprovedServices = new ArraySet<String>(1);
+            } else {
+                // Copy approved services.
+                newApprovedServices = new ArraySet<String>(oldApprovedServices);
+            }
+            newApprovedServices.add(serviceToAdd.flattenToShortString());
+
+            SharedPreferences.Editor editor = mPreferences.edit();
+            editor.putStringSet(APPROVED_SERVICES_PREFERENCE, newApprovedServices);
+            editor.apply();
+        }
+    }
+
+    /**
+     * Add a {@link OnSharedPreferenceChangeListener} that listens for changes to the approved
+     * services. Should only be called while holding {@link #sLock} to synchronize against
+     * {@link #addApprovedService}.
+     *
+     * @param listener {@link OnSharedPreferenceChangeListener} to register
+     */
+    public void registerChangeListenerLocked(OnSharedPreferenceChangeListener listener) {
+        mPreferences.registerOnSharedPreferenceChangeListener(listener);
+    }
+
+    /**
+     * Unregister a listener registered in {@link #registerChangeListenerLocked}.
+     *
+     * @param listener {@link OnSharedPreferenceChangeListener} to unregister
+     */
+    public void unregisterChangeListener(OnSharedPreferenceChangeListener listener) {
+        mPreferences.unregisterOnSharedPreferenceChangeListener(listener);
+    }
+
+    /**
+     * If a {@link PrintService} is approved, remove it from the list of approved services.
+     *
+     * @param serviceToRemove The {@link ComponentName} of the {@link PrintService} to be removed
+     */
+    public void removeApprovedService(ComponentName serviceToRemove) {
+        synchronized (sLock) {
+            if (isApprovedService(serviceToRemove)) {
+                // Copy approved services.
+                ArraySet<String> approvedServices = new ArraySet<String>(
+                        mPreferences.getStringSet(APPROVED_SERVICES_PREFERENCE, null));
+
+                SharedPreferences.Editor editor = mPreferences.edit();
+
+                final int numApprovedServices = approvedServices.size();
+                for (int i = 0; i < numApprovedServices; i++) {
+                    if (approvedServices.valueAt(i)
+                            .equals(serviceToRemove.flattenToShortString())) {
+                        approvedServices.removeAt(i);
+                        break;
+                    }
+                }
+
+                editor.putStringSet(APPROVED_SERVICES_PREFERENCE, approvedServices);
+                editor.apply();
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/res/layout-television/settings_with_drawer.xml b/packages/SettingsLib/res/layout-television/settings_with_drawer.xml
new file mode 100644
index 0000000..e8ca691
--- /dev/null
+++ b/packages/SettingsLib/res/layout-television/settings_with_drawer.xml
@@ -0,0 +1,20 @@
+<!--
+    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:id="@+id/content_frame"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
diff --git a/packages/SettingsLib/res/layout-watch/settings_with_drawer.xml b/packages/SettingsLib/res/layout-watch/settings_with_drawer.xml
new file mode 100644
index 0000000..e8ca691
--- /dev/null
+++ b/packages/SettingsLib/res/layout-watch/settings_with_drawer.xml
@@ -0,0 +1,20 @@
+<!--
+    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:id="@+id/content_frame"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 549c042..afffe6d 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> word ten volle ondersteun"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> vereis netwerkverbinding"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> word nie ondersteun nie"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Kontroleer tans …"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Instellings vir <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Lanseer enjin-instellings"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Voorkeur-enjin"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Algemeen"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Baie stadig"</item>
+    <item msgid="4795095314303559268">"Stadig"</item>
+    <item msgid="8903157781070679765">"Normaal"</item>
+    <item msgid="164347302621392996">"Vinnig"</item>
+    <item msgid="5794028588101562009">"Vinniger"</item>
+    <item msgid="7163942783888652942">"Baie vinnig"</item>
+    <item msgid="7831712693748700507">"Snel"</item>
+    <item msgid="5194774745031751806">"Baie snel"</item>
+    <item msgid="9085102246155045744">"Vinnigste"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Kies profiel"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Persoonlik"</string>
+    <string name="category_work" msgid="8699184680584175622">"Werk"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index eebd819..0e29d8e 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ሙሉ ለሙሉ ይደገፋል"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> የአውታረ መረብ ግንኙነት ያስፈልጋል"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> አይደገፍም"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"በማረጋገጥ ላይ…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"የ<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> ቅንብሮች"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"የፍርግም ቅንብሮችን ያስጀምሩ"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"የተመረጠ ፍርግም"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"አጠቃላይ"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"በጣም ቀርፋፋ"</item>
+    <item msgid="4795095314303559268">"ቀርፋፋ"</item>
+    <item msgid="8903157781070679765">"መደበኛ"</item>
+    <item msgid="164347302621392996">"ፈጣን"</item>
+    <item msgid="5794028588101562009">"በጣም ፈጣን"</item>
+    <item msgid="7163942783888652942">"እጅግ በጣም ፈጣን"</item>
+    <item msgid="7831712693748700507">"ቀልጣፋ"</item>
+    <item msgid="5194774745031751806">"በጣም ቀልጣፋ"</item>
+    <item msgid="9085102246155045744">"እጅግ በጣም ቀልጣፋ"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"መገለጫ ይምረጡ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"የግል"</string>
+    <string name="category_work" msgid="8699184680584175622">"ስራ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 948b37f..89c661c 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> متوافقة تمامًا"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> تتطلب اتصالاً بالشبكة"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> غير متوافقة"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"جارٍ التحقق…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"إعدادات <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"تشغيل إعدادات المحرك"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"المحرك المفضل"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"عامة"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"بطيء جدًا"</item>
+    <item msgid="4795095314303559268">"بطيء"</item>
+    <item msgid="8903157781070679765">"عادي"</item>
+    <item msgid="164347302621392996">"سريع"</item>
+    <item msgid="5794028588101562009">"أسرع"</item>
+    <item msgid="7163942783888652942">"سريع جدًا"</item>
+    <item msgid="7831712693748700507">"خاطف"</item>
+    <item msgid="5194774745031751806">"خاطف جدًا"</item>
+    <item msgid="9085102246155045744">"الأسرع"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"اختيار ملف شخصي"</string>
+    <string name="category_personal" msgid="1299663247844969448">"شخصي"</string>
+    <string name="category_work" msgid="8699184680584175622">"العمل"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index e956843..cb73beb 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Çox tez"</item>
     <item msgid="9085102246155045744">"Ən sürətli"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profil Seçin"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Şəxsi"</string>
+    <string name="category_work" msgid="8699184680584175622">"İş"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index afba421..5e9eacd 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> се поддържа напълно"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"За <xliff:g id="LOCALE">%1$s</xliff:g> се изисква връзка с мрежа"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> не се поддържа"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Извършва се проверка…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Настройки за <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Стартиране на настройките на машината"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Предпочитана машина"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Общи"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Много бавна"</item>
+    <item msgid="4795095314303559268">"Бавна"</item>
+    <item msgid="8903157781070679765">"Нормална"</item>
+    <item msgid="164347302621392996">"Бърза"</item>
+    <item msgid="5794028588101562009">"По-бърза"</item>
+    <item msgid="7163942783888652942">"Много бърза"</item>
+    <item msgid="7831712693748700507">"Изключително бърза"</item>
+    <item msgid="5194774745031751806">"Свръхбърза"</item>
+    <item msgid="9085102246155045744">"Най-бърза"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Избиране на потр. профил"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Лични"</string>
+    <string name="category_work" msgid="8699184680584175622">"Служебни"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index 00aeac9..786e7d6 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> সম্পূর্ণ সমর্থিত"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> এর নেটওয়ার্ক সংযোগের প্রয়োজন"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> সমর্থিত নয়"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"পরীক্ষা করা হচ্ছে..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> জন্য সেটিংস"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"ইঞ্জিন সেটিংস লঞ্চ করুন"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"পছন্দের ইঞ্জিন"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"সাধারণ"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"অত্যন্ত ধীরে"</item>
+    <item msgid="4795095314303559268">"ধীর"</item>
+    <item msgid="8903157781070679765">"স্বাভাবিক"</item>
+    <item msgid="164347302621392996">"দ্রুত"</item>
+    <item msgid="5794028588101562009">"আরো দ্রুত"</item>
+    <item msgid="7163942783888652942">"খুব দ্রুত"</item>
+    <item msgid="7831712693748700507">"দ্রুত"</item>
+    <item msgid="5194774745031751806">"খুব দ্রুত"</item>
+    <item msgid="9085102246155045744">"দ্রুততম"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"প্রোফাইল বেছে নিন"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ব্যক্তিগত"</string>
+    <string name="category_work" msgid="8699184680584175622">"কর্মক্ষেত্র"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 9536b7f..28f196f 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> és totalment compatible"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Es necessita una connexió de xarxa per a <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> no és compatible"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"S\'està comprovant…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Configuració de: <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Obre la configuració del motor"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor preferit"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Molt lenta"</item>
+    <item msgid="4795095314303559268">"Lenta"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Ràpida"</item>
+    <item msgid="5794028588101562009">"Més ràpida"</item>
+    <item msgid="7163942783888652942">"Molt ràpida"</item>
+    <item msgid="7831712693748700507">"Veloç"</item>
+    <item msgid="5194774745031751806">"Molt veloç"</item>
+    <item msgid="9085102246155045744">"Màxima"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Triar un perfil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Feina"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 693f954..c14278a 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Jazyk <xliff:g id="LOCALE">%1$s</xliff:g> je plně podporován"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Jazyk <xliff:g id="LOCALE">%1$s</xliff:g> vyžaduje připojení k síti"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Jazyk <xliff:g id="LOCALE">%1$s</xliff:g> není podporován"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Probíhá kontrola…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Spustit vyhledávač"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferovaný modul"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Obecné"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Velmi pomalá"</item>
+    <item msgid="4795095314303559268">"Pomalá"</item>
+    <item msgid="8903157781070679765">"Normální"</item>
+    <item msgid="164347302621392996">"Mírně rychlá"</item>
+    <item msgid="5794028588101562009">"Středně rychlá"</item>
+    <item msgid="7163942783888652942">"Rychlá"</item>
+    <item msgid="7831712693748700507">"Velmi rychlá"</item>
+    <item msgid="5194774745031751806">"Ultra rychlá"</item>
+    <item msgid="9085102246155045744">"Nejrychlejší"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Vyberte profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Osobní"</string>
+    <string name="category_work" msgid="8699184680584175622">"Pracovní"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 3d4c8d4..ed7d0db 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> er fuldt understøttet"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> kræver netværksforbindelse"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> understøttes ikke"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Kontrollerer…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Indstillinger for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Åbn indstillinger for maskinen"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Foretrukken maskine"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Generelt"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Meget langsom"</item>
+    <item msgid="4795095314303559268">"Langsom"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Hurtig"</item>
+    <item msgid="5794028588101562009">"Hurtigere"</item>
+    <item msgid="7163942783888652942">"Meget hurtig"</item>
+    <item msgid="7831712693748700507">"Lynhurtig"</item>
+    <item msgid="5194774745031751806">"Ekstra lynhurtig"</item>
+    <item msgid="9085102246155045744">"Hurtigst"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Vælg profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personlig"</string>
+    <string name="category_work" msgid="8699184680584175622">"Arbejde"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 6d1c899..6f38bb3 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> wird vollständig unterstützt."</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> erfordert eine Netzwerkverbindung."</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> wird nicht unterstützt."</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Wird überprüft…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Einstellungen für <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Einstellungen der Suchmaschine starten"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Bevorzugtes Modul"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Allgemein"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Sehr langsam"</item>
+    <item msgid="4795095314303559268">"Langsam"</item>
+    <item msgid="8903157781070679765">"Mittel"</item>
+    <item msgid="164347302621392996">"Schnell"</item>
+    <item msgid="5794028588101562009">"Schneller"</item>
+    <item msgid="7163942783888652942">"Sehr schnell"</item>
+    <item msgid="7831712693748700507">"Schnell"</item>
+    <item msgid="5194774745031751806">"Sehr schnell"</item>
+    <item msgid="9085102246155045744">"Am schnellsten"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profil auswählen"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Nutzer"</string>
+    <string name="category_work" msgid="8699184680584175622">"Geschäftlich"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index e3d19af..25ab5b8 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Τα <xliff:g id="LOCALE">%1$s</xliff:g> υποστηρίζονται πλήρως"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Τα <xliff:g id="LOCALE">%1$s</xliff:g> απαιτούν σύνδεση δικτύου"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Δεν υποστηρίζονται τα <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Έλεγχος…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Ρυθμίσεις για: <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Εκκίνηση ρυθμίσεων μηχανής"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Προτεινόμενη μηχανή"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Γενικά"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Πολύ αργή"</item>
+    <item msgid="4795095314303559268">"Αργή"</item>
+    <item msgid="8903157781070679765">"Κανονική"</item>
+    <item msgid="164347302621392996">"Γρήγορη"</item>
+    <item msgid="5794028588101562009">"Πιο γρήγορη"</item>
+    <item msgid="7163942783888652942">"Πολύ γρήγορη"</item>
+    <item msgid="7831712693748700507">"Ταχεία"</item>
+    <item msgid="5194774745031751806">"Εξαιρετικά ταχεία"</item>
+    <item msgid="9085102246155045744">"Ταχύτατη"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Επιλογή προφίλ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Προσωπικό"</string>
+    <string name="category_work" msgid="8699184680584175622">"Εργασία"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 1138779..0e7ebd8 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> is fully supported"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requires network connection"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> is not supported"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Checking…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Settings for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Launch engine settings"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferred engine"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Very slow"</item>
+    <item msgid="4795095314303559268">"Slow"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Fast"</item>
+    <item msgid="5794028588101562009">"Faster"</item>
+    <item msgid="7163942783888652942">"Very fast"</item>
+    <item msgid="7831712693748700507">"Rapid"</item>
+    <item msgid="5194774745031751806">"Very rapid"</item>
+    <item msgid="9085102246155045744">"Fastest"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Work"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 1138779..0e7ebd8 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> is fully supported"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requires network connection"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> is not supported"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Checking…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Settings for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Launch engine settings"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferred engine"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Very slow"</item>
+    <item msgid="4795095314303559268">"Slow"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Fast"</item>
+    <item msgid="5794028588101562009">"Faster"</item>
+    <item msgid="7163942783888652942">"Very fast"</item>
+    <item msgid="7831712693748700507">"Rapid"</item>
+    <item msgid="5194774745031751806">"Very rapid"</item>
+    <item msgid="9085102246155045744">"Fastest"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Work"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 1138779..0e7ebd8 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> is fully supported"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requires network connection"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> is not supported"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Checking…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Settings for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Launch engine settings"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferred engine"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Very slow"</item>
+    <item msgid="4795095314303559268">"Slow"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Fast"</item>
+    <item msgid="5794028588101562009">"Faster"</item>
+    <item msgid="7163942783888652942">"Very fast"</item>
+    <item msgid="7831712693748700507">"Rapid"</item>
+    <item msgid="5194774745031751806">"Very rapid"</item>
+    <item msgid="9085102246155045744">"Fastest"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Choose Profile"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Work"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 3a6ca10..013d576 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"El idioma <xliff:g id="LOCALE">%1$s</xliff:g> es totalmente compatible."</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"El idioma <xliff:g id="LOCALE">%1$s</xliff:g> requiere una conexión de red."</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"El idioma <xliff:g id="LOCALE">%1$s</xliff:g> no es compatible."</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Comprobando…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Configuración de <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Iniciar configuración de motor"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor preferido"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Muy lenta"</item>
+    <item msgid="4795095314303559268">"Lenta"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Ligera"</item>
+    <item msgid="5794028588101562009">"Muy ligera"</item>
+    <item msgid="7163942783888652942">"A velocidad muy alta"</item>
+    <item msgid="7831712693748700507">"Rápida"</item>
+    <item msgid="5194774745031751806">"Muy rápida"</item>
+    <item msgid="9085102246155045744">"A velocidad máxima"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Elegir perfil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Trabajo"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 9bd8462..317b37a 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Hiperrrápida"</item>
     <item msgid="9085102246155045744">"La más rápida"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Seleccionar perfil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Trabajo"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index 820c701..366c336 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Väga tormakas"</item>
     <item msgid="9085102246155045744">"Kõige kiirem"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profiili valimine"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Isiklik"</string>
+    <string name="category_work" msgid="8699184680584175622">"Töö"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 990960d..68591cf 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> guztiz onartzen da."</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> eskualde-ezarpenak sareko konexioa behar du"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Ez da <xliff:g id="LOCALE">%1$s</xliff:g> onartzen"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Egiaztatzen…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> motorraren ezarpenak"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Abiarazi motorraren ezarpenak"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor hobetsia"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Orokorra"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Oso motela"</item>
+    <item msgid="4795095314303559268">"Motela"</item>
+    <item msgid="8903157781070679765">"Normala"</item>
+    <item msgid="164347302621392996">"Bizkorra"</item>
+    <item msgid="5794028588101562009">"Bizkorragoa"</item>
+    <item msgid="7163942783888652942">"Oso bizkorra"</item>
+    <item msgid="7831712693748700507">"Bizkorra"</item>
+    <item msgid="5194774745031751806">"Oso bizkorra"</item>
+    <item msgid="9085102246155045744">"Bizkorrena"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Aukeratu profila"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Pertsonalak"</string>
+    <string name="category_work" msgid="8699184680584175622">"Lanekoak"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 387a43e..fa9983a 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> کاملاً پشتیبانی می‌شود"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> به اتصال شبکه نیاز دارد"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> پشتیبانی نمی‌شود"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"در حال بررسی…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"تنظیمات برای <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"راه‌اندازی تنظیمات موتور"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"موتور ترجیحی"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"کلی"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"بسیار آهسته"</item>
+    <item msgid="4795095314303559268">"آهسته"</item>
+    <item msgid="8903157781070679765">"معمولی"</item>
+    <item msgid="164347302621392996">"سریع"</item>
+    <item msgid="5794028588101562009">"سریع‌تر"</item>
+    <item msgid="7163942783888652942">"خیلی سریع"</item>
+    <item msgid="7831712693748700507">"تند"</item>
+    <item msgid="5194774745031751806">"خیلی تند"</item>
+    <item msgid="9085102246155045744">"سریع‌ترین"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"انتخاب نمایه"</string>
+    <string name="category_personal" msgid="1299663247844969448">"شخصی"</string>
+    <string name="category_work" msgid="8699184680584175622">"محل کار"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index e6400c32..2037885 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Kieltä <xliff:g id="LOCALE">%1$s</xliff:g> tuetaan"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Kieli <xliff:g id="LOCALE">%1$s</xliff:g> tarvitsee yhteyden verkostoon"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Kieltä <xliff:g id="LOCALE">%1$s</xliff:g> ei tueta"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Tarkistetaan…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Asetukset: <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Käynnistä moottorin asetukset"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Ensisijainen kone"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Yleiset"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Hyvin hidas"</item>
+    <item msgid="4795095314303559268">"Hidas"</item>
+    <item msgid="8903157781070679765">"Normaali"</item>
+    <item msgid="164347302621392996">"Nopea"</item>
+    <item msgid="5794028588101562009">"Nopeampi"</item>
+    <item msgid="7163942783888652942">"Hyvin nopea"</item>
+    <item msgid="7831712693748700507">"Nopea"</item>
+    <item msgid="5194774745031751806">"Erittäin nopea"</item>
+    <item msgid="9085102246155045744">"Nopein"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Valitse profiili"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Henkilökohtainen"</string>
+    <string name="category_work" msgid="8699184680584175622">"Työ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 9e1a5a0..da22cf9 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Les paramètres régionaux <xliff:g id="LOCALE">%1$s</xliff:g> sont compatibles"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Les paramètres régionaux <xliff:g id="LOCALE">%1$s</xliff:g> nécessitent une connexion réseau"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Les paramètres régionaux <xliff:g id="LOCALE">%1$s</xliff:g> ne sont pas compatibles"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Vérification en cours…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Paramètres de <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Lancer les paramètres du moteur"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Moteur préféré"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Général"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Très lente"</item>
+    <item msgid="4795095314303559268">"Lente"</item>
+    <item msgid="8903157781070679765">"Normale"</item>
+    <item msgid="164347302621392996">"Rapide"</item>
+    <item msgid="5794028588101562009">"Plus rapide"</item>
+    <item msgid="7163942783888652942">"Très rapide"</item>
+    <item msgid="7831712693748700507">"Rapide"</item>
+    <item msgid="5194774745031751806">"Très rapide"</item>
+    <item msgid="9085102246155045744">"La plus rapide"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Sélectionnez un profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personnel"</string>
+    <string name="category_work" msgid="8699184680584175622">"Travail"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 0e3265f..9609ff9 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Les paramètres régionaux <xliff:g id="LOCALE">%1$s</xliff:g> sont compatibles."</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Les paramètres régionaux <xliff:g id="LOCALE">%1$s</xliff:g> nécessitent une connexion réseau."</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Les paramètres régionaux <xliff:g id="LOCALE">%1$s</xliff:g> ne sont pas compatibles."</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Vérification…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Paramètres de <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Lancer les paramètres du moteur"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Moteur préféré"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Paramètres généraux"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Très lente"</item>
+    <item msgid="4795095314303559268">"Lente"</item>
+    <item msgid="8903157781070679765">"Normale"</item>
+    <item msgid="164347302621392996">"Rapide"</item>
+    <item msgid="5794028588101562009">"Plus rapide"</item>
+    <item msgid="7163942783888652942">"Très rapide"</item>
+    <item msgid="7831712693748700507">"Rapide"</item>
+    <item msgid="5194774745031751806">"Très rapide"</item>
+    <item msgid="9085102246155045744">"La plus rapide"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Sélectionner un profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personnel"</string>
+    <string name="category_work" msgid="8699184680584175622">"Professionnel"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index 7c6c502..ffede7e 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é completamente compatible"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> require unha conexión de rede"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Non se admite <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Comprobando..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Configuración de <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Iniciar configuración do motor"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor preferido"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Xeral"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Moi lento"</item>
+    <item msgid="4795095314303559268">"Lento"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Rápido"</item>
+    <item msgid="5794028588101562009">"Máis rápido"</item>
+    <item msgid="7163942783888652942">"Moi rápido"</item>
+    <item msgid="7831712693748700507">"Rápido"</item>
+    <item msgid="5194774745031751806">"Moi rápido"</item>
+    <item msgid="9085102246155045744">"O máis rápido"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Seleccionar perfil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Persoal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Traballo"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index cdecea9..d515899 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"ખૂબ જ તીવ્ર"</item>
     <item msgid="9085102246155045744">"સૌથી ઝડપી"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"પ્રોફાઇલ પસંદ કરો"</string>
+    <string name="category_personal" msgid="1299663247844969448">"વ્યક્તિગત"</string>
+    <string name="category_work" msgid="8699184680584175622">"કાર્યાલય"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index bab59aa..abcbdbd 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"अत्यधिक तीव्र"</item>
     <item msgid="9085102246155045744">"सबसे तेज़"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"प्रोफ़ाइल चुनें"</string>
+    <string name="category_personal" msgid="1299663247844969448">"व्यक्तिगत"</string>
+    <string name="category_work" msgid="8699184680584175622">"कार्यालय"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 77c3d26..7516959 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> je u potpunosti podržan"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> zahtijeva mrežnu vezu"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> nije podržan"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Provjeravanje…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Postavke za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Postavke pokretanja alata"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Željeni alat"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Opće"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Vrlo sporo"</item>
+    <item msgid="4795095314303559268">"Sporo"</item>
+    <item msgid="8903157781070679765">"Uobičajeno"</item>
+    <item msgid="164347302621392996">"Brzo"</item>
+    <item msgid="5794028588101562009">"Brže"</item>
+    <item msgid="7163942783888652942">"Vrlo brzo"</item>
+    <item msgid="7831712693748700507">"Ubrzano"</item>
+    <item msgid="5194774745031751806">"Vrlo ubrzano"</item>
+    <item msgid="9085102246155045744">"Najbrže"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Odabir profila"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Osobno"</string>
+    <string name="category_work" msgid="8699184680584175622">"Posao"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index e3ecdcc..77c944d 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"A(z) <xliff:g id="LOCALE">%1$s</xliff:g> nyelv teljes támogatást élvez"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"A(z) <xliff:g id="LOCALE">%1$s</xliff:g> nyelv használatához hálózati kapcsolatra van szükség"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"A(z) <xliff:g id="LOCALE">%1$s</xliff:g> nyelvet nem támogatja a rendszer"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Ellenőrzés…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"A(z) <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> beállításai"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Keresőmotor beállításainak indítása"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferált motor"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Általános"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Nagyon lassú"</item>
+    <item msgid="4795095314303559268">"Lassú"</item>
+    <item msgid="8903157781070679765">"Normál"</item>
+    <item msgid="164347302621392996">"Gyors"</item>
+    <item msgid="5794028588101562009">"Gyorsabb"</item>
+    <item msgid="7163942783888652942">"Nagyon gyors"</item>
+    <item msgid="7831712693748700507">"Igen gyors"</item>
+    <item msgid="5194774745031751806">"Rendkívül gyors"</item>
+    <item msgid="9085102246155045744">"Leggyorsabb"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profil kiválasztása"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Személyes"</string>
+    <string name="category_work" msgid="8699184680584175622">"Munkahelyi"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index 2819ebb..ae8bab4 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g>-ը լիովին աջակցվում է"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g>-ը պահանջում է ցանցային կապ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g>-ը չի աջակցվում"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Ստուգվում է…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Կարգավորումներ <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>-ի համար"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Գործարկման շարժիչի կարգավորումներ"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Նախընտրած շարժիչը"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Ընդհանուր"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Շատ դանդաղ"</item>
+    <item msgid="4795095314303559268">"Դանդաղ"</item>
+    <item msgid="8903157781070679765">"Սովորական"</item>
+    <item msgid="164347302621392996">"Արագ"</item>
+    <item msgid="5794028588101562009">"Ավելի արագ"</item>
+    <item msgid="7163942783888652942">"Շատ արագ"</item>
+    <item msgid="7831712693748700507">"Սրընթաց"</item>
+    <item msgid="5194774745031751806">"Չափազանց արագ"</item>
+    <item msgid="9085102246155045744">"Ամենաարագ"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Ընտրել պրոֆիլ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Անձնական"</string>
+    <string name="category_work" msgid="8699184680584175622">"Աշխատանքային"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index bc1f0e8..3033afa 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> didukung sepenuhnya"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> membutuhkan sambungan jaringan"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> tidak didukung"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Memeriksa…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Setelan untuk <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Luncurkan setelan mesin"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Mesin yang dipilih"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Umum"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Sangat lambat"</item>
+    <item msgid="4795095314303559268">"Lambat"</item>
+    <item msgid="8903157781070679765">"Biasa"</item>
+    <item msgid="164347302621392996">"Cepat"</item>
+    <item msgid="5794028588101562009">"Lebih cepat"</item>
+    <item msgid="7163942783888652942">"Sangat cepat"</item>
+    <item msgid="7831712693748700507">"Cepat sekali"</item>
+    <item msgid="5194774745031751806">"Sangat cepat sekali"</item>
+    <item msgid="9085102246155045744">"Tercepat"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Pilih Profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Pribadi"</string>
+    <string name="category_work" msgid="8699184680584175622">"Kantor"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 458463d..21f80f4 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> er með fullan stuðning"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> krefst nettengingar"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> er ekki studd"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Athugar..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Stillingar fyrir <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Stillingar vélarræsingar"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Valin vél"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Almennt"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Mjög hægt"</item>
+    <item msgid="4795095314303559268">"Hægt"</item>
+    <item msgid="8903157781070679765">"Venjulegt"</item>
+    <item msgid="164347302621392996">"Hratt"</item>
+    <item msgid="5794028588101562009">"Hraðar"</item>
+    <item msgid="7163942783888652942">"Mjög hratt"</item>
+    <item msgid="7831712693748700507">"Leifturhratt"</item>
+    <item msgid="5194774745031751806">"Næsthraðast"</item>
+    <item msgid="9085102246155045744">"Hraðast"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Veldu snið"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Persónulegt"</string>
+    <string name="category_work" msgid="8699184680584175622">"Vinna"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 4042c6f..c2ad84e 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> completamente supportato"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> richiede connessione di rete"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> non supportato"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Verifica…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Impostazioni per <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Avvia impostazioni del motore"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motore preferito"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Generali"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Molto lenta"</item>
+    <item msgid="4795095314303559268">"Lenta"</item>
+    <item msgid="8903157781070679765">"Normale"</item>
+    <item msgid="164347302621392996">"Veloce"</item>
+    <item msgid="5794028588101562009">"Più veloce"</item>
+    <item msgid="7163942783888652942">"Molto veloce"</item>
+    <item msgid="7831712693748700507">"Rapida"</item>
+    <item msgid="5194774745031751806">"Molto rapida"</item>
+    <item msgid="9085102246155045744">"Massima velocità"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Scegli profilo"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personali"</string>
+    <string name="category_work" msgid="8699184680584175622">"Lavoro"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index cf055ae..b025a0d 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> נתמכת באופן מלא"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> מצריכה חיבור לרשת"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> אינה נתמכת"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"בודק…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"הגדרות עבור <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"השק הגדרות מנוע"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"מנוע מועדף"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"כללי"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"איטי מאוד"</item>
+    <item msgid="4795095314303559268">"איטי"</item>
+    <item msgid="8903157781070679765">"רגיל"</item>
+    <item msgid="164347302621392996">"מהיר"</item>
+    <item msgid="5794028588101562009">"מהיר יותר"</item>
+    <item msgid="7163942783888652942">"מהיר מאוד"</item>
+    <item msgid="7831712693748700507">"מהיר במיוחד"</item>
+    <item msgid="5194774745031751806">"יותר מהיר ממהיר במיוחד"</item>
+    <item msgid="9085102246155045744">"הכי מהיר"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"בחר פרופיל"</string>
+    <string name="category_personal" msgid="1299663247844969448">"אישי"</string>
+    <string name="category_work" msgid="8699184680584175622">"עבודה"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 9622df4..6a44854 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g>は完全サポート対象です"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g>ではネットワーク接続が必要です"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g>はサポート対象ではありません"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"確認しています…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>の設定"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"エンジン設定を起動"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"優先するエンジン"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"全般"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"非常に遅い"</item>
+    <item msgid="4795095314303559268">"遅い"</item>
+    <item msgid="8903157781070679765">"標準"</item>
+    <item msgid="164347302621392996">"速い"</item>
+    <item msgid="5794028588101562009">"より速い"</item>
+    <item msgid="7163942783888652942">"非常に速い"</item>
+    <item msgid="7831712693748700507">"高速"</item>
+    <item msgid="5194774745031751806">"非常に高速"</item>
+    <item msgid="9085102246155045744">"最高速"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"プロファイルの選択"</string>
+    <string name="category_personal" msgid="1299663247844969448">"個人用"</string>
+    <string name="category_work" msgid="8699184680584175622">"仕事用"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 8803e59..da5aa46 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> სრულად მხარდაჭერილია"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ითხოვს ქსელის კავშირს"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> არ არის მხარდაჭერილი"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"შემოწმება..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> პარამეტრები"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"ძრავის პარამეტრების გაშვება"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"რჩეული ძრავი"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"ზოგადი"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ძალიან ნელი"</item>
+    <item msgid="4795095314303559268">"ნელი"</item>
+    <item msgid="8903157781070679765">"ჩვეულებრივი"</item>
+    <item msgid="164347302621392996">"სწრაფი"</item>
+    <item msgid="5794028588101562009">"უფრო სწრაფი"</item>
+    <item msgid="7163942783888652942">"ძალიან სწრაფი"</item>
+    <item msgid="7831712693748700507">"ჩქარი"</item>
+    <item msgid="5194774745031751806">"ძალიან ჩქარი"</item>
+    <item msgid="9085102246155045744">"უსწრაფესი"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"პროფილის არჩევა"</string>
+    <string name="category_personal" msgid="1299663247844969448">"პირადი"</string>
+    <string name="category_work" msgid="8699184680584175622">"სამსახური"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index 2e5add7..179e4af 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> тілінің қолдауы бар"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> желі байланысын қажет етеді"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> үшін қолдау ұсынылмаған"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Тексерілуде…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> параметрлері"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Қозғалтқыш параметрлерін қосу"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Қалаулы қозғалтқыш"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Жалпы"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Өте баяу"</item>
+    <item msgid="4795095314303559268">"Баяу"</item>
+    <item msgid="8903157781070679765">"Қалыпты"</item>
+    <item msgid="164347302621392996">"Жылдам"</item>
+    <item msgid="5794028588101562009">"Жылдамырақ"</item>
+    <item msgid="7163942783888652942">"Өте жылдам"</item>
+    <item msgid="7831712693748700507">"Тез"</item>
+    <item msgid="5194774745031751806">"Өте тез"</item>
+    <item msgid="9085102246155045744">"Ең тез"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Профильді таңдау"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Жеке"</string>
+    <string name="category_work" msgid="8699184680584175622">"Жұмыс"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index 57389a1..dd13d21 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"បាន​គាំទ្រ​ពេញលេញ <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ទាមទារ​ការ​ភ្ជាប់​បណ្ដាញ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"មិន​គាំទ្រ <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"កំពុងពិនិត្យ..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"ការ​កំណត់​សម្រាប់ <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"ចាប់ផ្ដើម​ការកំណត់​ម៉ាស៊ីន​ផ្សេង"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ម៉ាស៊ីន​ដែល​ពេញ​ចិត្ត"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"ទូទៅ"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"យឺតខ្លាំង"</item>
+    <item msgid="4795095314303559268">"យឺត"</item>
+    <item msgid="8903157781070679765">"ធម្មតា"</item>
+    <item msgid="164347302621392996">"លឿន"</item>
+    <item msgid="5794028588101562009">"លឿនជាង"</item>
+    <item msgid="7163942783888652942">"លឿនខ្លាំង"</item>
+    <item msgid="7831712693748700507">"រហ័ស"</item>
+    <item msgid="5194774745031751806">"រហ័សខ្លាំង"</item>
+    <item msgid="9085102246155045744">"លឿនបំផុត"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"ជ្រើសប្រវត្តិរូប"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ផ្ទាល់ខ្លួន"</string>
+    <string name="category_work" msgid="8699184680584175622">"កន្លែង​ធ្វើការ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index 1b53bfe..a3586b8 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ಸಂಪೂರ್ಣವಾಗಿ ಬೆಂಬಲಿತವಾಗಿದೆ"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕದ ಅಗತ್ಯವಿದೆ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> ಗಾಗಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"ಎಂಜಿನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪ್ರಾರಂಭಿಸು"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ಪ್ರಾಶಸ್ತ್ಯದ ಎಂಜಿನ್"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"ಸಾಮಾನ್ಯ"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ತುಂಬಾ ನಿಧಾನ"</item>
+    <item msgid="4795095314303559268">"ನಿಧಾನ"</item>
+    <item msgid="8903157781070679765">"ಸಾಮಾನ್ಯ"</item>
+    <item msgid="164347302621392996">"ವೇಗ"</item>
+    <item msgid="5794028588101562009">"ಕ್ಷಿಪ್ರ"</item>
+    <item msgid="7163942783888652942">"ಅತ್ಯಂತ ವೇಗ"</item>
+    <item msgid="7831712693748700507">"ತ್ವರಿತ"</item>
+    <item msgid="5194774745031751806">"ಅತ್ಯಂತ ತ್ವರಿತ"</item>
+    <item msgid="9085102246155045744">"ಅತಿ ಕ್ಷಿಪ್ರ"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"ಪ್ರೊಫೈಲ್ ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ವೈಯಕ್ತಿಕ"</string>
+    <string name="category_work" msgid="8699184680584175622">"ಕೆಲಸದ ಸ್ಥಳ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f0ff60f..745fb5b 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g>은(는) 완전하게 지원됩니다."</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g>은(는) 네트워크 연결이 필요합니다."</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g>은(는) 지원되지 않습니다."</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"확인 중…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>에 대한 설정"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"엔진 설정 실행"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"기본 엔진"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"기본설정"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"매우 느리게"</item>
+    <item msgid="4795095314303559268">"느리게"</item>
+    <item msgid="8903157781070679765">"보통"</item>
+    <item msgid="164347302621392996">"빠르게"</item>
+    <item msgid="5794028588101562009">"더 빠르게"</item>
+    <item msgid="7163942783888652942">"매우 빠르게"</item>
+    <item msgid="7831712693748700507">"상당히 빠르게"</item>
+    <item msgid="5194774745031751806">"매우 빠르게"</item>
+    <item msgid="9085102246155045744">"가장 빠르게"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"프로필 선택"</string>
+    <string name="category_personal" msgid="1299663247844969448">"개인"</string>
+    <string name="category_work" msgid="8699184680584175622">"직장"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 430c8e2..946f55b 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> толук колдоого алынган"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> желеге туташууну талап кылат"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> колдоого алынган эмес"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Текшерилүүдө…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> жөндөөлөрдү"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Жарак тууралоолорун ачуу"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Тандалган жарак"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Жалпы"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Өтө жай"</item>
+    <item msgid="4795095314303559268">"Жай"</item>
+    <item msgid="8903157781070679765">"Орточо"</item>
+    <item msgid="164347302621392996">"Ылдам"</item>
+    <item msgid="5794028588101562009">"Ылдамыраак"</item>
+    <item msgid="7163942783888652942">"Абдан ылдам"</item>
+    <item msgid="7831712693748700507">"Тез"</item>
+    <item msgid="5194774745031751806">"Өтө тез"</item>
+    <item msgid="9085102246155045744">"Эң ылдам"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Профиль тандоо"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Жеке"</string>
+    <string name="category_work" msgid="8699184680584175622">"Жумуш"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index 29b27b3..894d4d9 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"ຮອງຮັບ <xliff:g id="LOCALE">%1$s</xliff:g> ເຕັມຮູບແບບ"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ຕ້ອງການການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"ບໍ່ຮອງຮັບ <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"ກຳລັງກວດສອບ..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"ການຕັ້ງຄ່າສຳລັບ <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"ເປີດການຕັ້ງຄ່າລະບົບສະເຄາະສຽງ"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ລະບົບທີ່ຕ້ອງການ"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"ທົ່ວໄປ"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ຊ້າຫຼາຍ"</item>
+    <item msgid="4795095314303559268">"ຊ້າ"</item>
+    <item msgid="8903157781070679765">"ປົກ​ກ​ະ​ຕິ"</item>
+    <item msgid="164347302621392996">"ໄວ"</item>
+    <item msgid="5794028588101562009">"ໄວກວ່າ"</item>
+    <item msgid="7163942783888652942">"ໄວຫຼາຍ"</item>
+    <item msgid="7831712693748700507">"ໄວ"</item>
+    <item msgid="5194774745031751806">"ໄວສຸດໆ"</item>
+    <item msgid="9085102246155045744">"ໄວທີ່ສຸດ"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"ເລືອກ​ໂປ​ຣ​ໄຟ​ລ໌"</string>
+    <string name="category_personal" msgid="1299663247844969448">"​ສ່ວນ​ໂຕ"</string>
+    <string name="category_work" msgid="8699184680584175622">"​ບ່ອນ​ເຮັດ​ວຽກ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 3264838..132ad1f 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Labai spartus"</item>
     <item msgid="9085102246155045744">"Greičiausias"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profilio pasirinkimas"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Asmeninės"</string>
+    <string name="category_work" msgid="8699184680584175622">"Darbo"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 6fbc46a..f3dd7e7 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Lokalizācija <xliff:g id="LOCALE">%1$s</xliff:g> tiek pilnībā atbalstīta"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Lokalizācijai <xliff:g id="LOCALE">%1$s</xliff:g> nepieciešams tīkla savienojums."</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Lokalizācija <xliff:g id="LOCALE">%1$s</xliff:g> netiek atbalstīta"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Notiek pārbaude..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Programmas <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> iestatījumi"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Programmas iestatījumu palaišana"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Vēlamā programma"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Vispārīgi"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Ļoti lēni"</item>
+    <item msgid="4795095314303559268">"Lēni"</item>
+    <item msgid="8903157781070679765">"Normāli"</item>
+    <item msgid="164347302621392996">"Ātri"</item>
+    <item msgid="5794028588101562009">"Ātrāk"</item>
+    <item msgid="7163942783888652942">"Ļoti ātri"</item>
+    <item msgid="7831712693748700507">"Raiti"</item>
+    <item msgid="5194774745031751806">"Ļoti raiti"</item>
+    <item msgid="9085102246155045744">"Visātrāk"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profila izvēlēšanās"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Privāts"</string>
+    <string name="category_work" msgid="8699184680584175622">"Darba"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 94a6716..a6f45d2 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> е целосно поддржан"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> бара мрежно поврзување"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> не е поддржано"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Се проверува..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Подесувања на <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Стартувај подесувања на софтвер"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Претпочитан софтвер"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Општо"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Многу бавно"</item>
+    <item msgid="4795095314303559268">"Бавно"</item>
+    <item msgid="8903157781070679765">"Нормално"</item>
+    <item msgid="164347302621392996">"Брзо"</item>
+    <item msgid="5794028588101562009">"Побрзо"</item>
+    <item msgid="7163942783888652942">"Многу брзо"</item>
+    <item msgid="7831712693748700507">"Рапидно"</item>
+    <item msgid="5194774745031751806">"Многу рапидно"</item>
+    <item msgid="9085102246155045744">"Најбрзо"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Изберете профил"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Лични"</string>
+    <string name="category_work" msgid="8699184680584175622">"Работа"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 18f2991..16e33d1 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ഭാഷയെ പൂർണ്ണമായും പിന്തുണയ്‌ക്കുന്നു"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ഭാഷയ്‌ക്ക് നെറ്റ്‌വർക്ക് കണക്ഷൻ ആവശ്യമാണ്"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ഭാഷയെ പിന്തുണയ്‌ക്കുന്നില്ല"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"പരിശോധിക്കുന്നു…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> എന്നതിനായുള്ള ക്രമീകരണങ്ങൾ"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"എഞ്ചിൻ ക്രമീകരണങ്ങൾ സമാരംഭിക്കുക"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"തിരഞ്ഞെടുത്ത എഞ്ചിൻ"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"പൊതുവായ കാര്യങ്ങൾ"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"വളരെ കുറഞ്ഞ വേഗത്തിൽ"</item>
+    <item msgid="4795095314303559268">"കുറഞ്ഞ വേഗത്തിൽ"</item>
+    <item msgid="8903157781070679765">"സാധാരണ വേഗത്തിൽ"</item>
+    <item msgid="164347302621392996">"വേഗത്തിൽ"</item>
+    <item msgid="5794028588101562009">"കൂടുതൽ വേഗത്തിൽ"</item>
+    <item msgid="7163942783888652942">"വളരെ വേഗത്തിൽ"</item>
+    <item msgid="7831712693748700507">"ശീഘ്രം"</item>
+    <item msgid="5194774745031751806">"വളരെ ശീഘ്രം"</item>
+    <item msgid="9085102246155045744">"ഏറ്റവും വേഗത്തിൽ"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"പ്രൊഫൈൽ തിരഞ്ഞെടുക്കുക"</string>
+    <string name="category_personal" msgid="1299663247844969448">"വ്യക്തിഗതം"</string>
+    <string name="category_work" msgid="8699184680584175622">"ഔദ്യോഗികം"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index 77d272c..53c71a4 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> бүрэн дэмжигдсэн"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> сүлжээнд хrequires network connection"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> дэмжигдээгүй байна"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Шалгаж байна..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>-н тохиргоо"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Үүсгүүрийн тохиргоог ажиллуулах"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Давуу үүсгүүр"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Ерөнхий"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Маш удаан"</item>
+    <item msgid="4795095314303559268">"Удаан"</item>
+    <item msgid="8903157781070679765">"Хэвийн"</item>
+    <item msgid="164347302621392996">"Хурдан"</item>
+    <item msgid="5794028588101562009">"Илүү хурдан"</item>
+    <item msgid="7163942783888652942">"Маш хурдан"</item>
+    <item msgid="7831712693748700507">"Түргэн"</item>
+    <item msgid="5194774745031751806">"Маш түргэн"</item>
+    <item msgid="9085102246155045744">"Хамгийн хурдан"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Профайлаа сонгоно уу"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Хувийн"</string>
+    <string name="category_work" msgid="8699184680584175622">"Ажил"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index cb902a7..04d9d78 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> पूर्णपणे समर्थित आहे"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ला नेटवर्क कनेक्शनची आवश्यकता आहे"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> समर्थित नाही"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"तपासत आहे..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> साठी सेटिंग्ज"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"इंजिन सेटिंग्ज लाँच करा"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"प्राधान्यकृत इंजिन"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"सामान्य"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"खूप धीमे"</item>
+    <item msgid="4795095314303559268">"धीमे"</item>
+    <item msgid="8903157781070679765">"सामान्य"</item>
+    <item msgid="164347302621392996">"थोडे जलद"</item>
+    <item msgid="5794028588101562009">"जलद"</item>
+    <item msgid="7163942783888652942">"खूप जलद"</item>
+    <item msgid="7831712693748700507">"शीघ्र"</item>
+    <item msgid="5194774745031751806">"अतिशीघ्र"</item>
+    <item msgid="9085102246155045744">"जलद"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"प्रोफाईल निवडा"</string>
+    <string name="category_personal" msgid="1299663247844969448">"वैयक्तिक"</string>
+    <string name="category_work" msgid="8699184680584175622">"कार्य"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 52bfc05..e3ceddb 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Sangat pantas"</item>
     <item msgid="9085102246155045744">"Paling laju"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Pilih Profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Peribadi"</string>
+    <string name="category_work" msgid="8699184680584175622">"Tempat Kerja"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index 5307cf3..99c27c8 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"အရမ်းသွက်"</item>
     <item msgid="9085102246155045744">"အမြန်ဆုံး"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"ပရိုဖိုင်ရွေးရန်"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ကိုယ်ရေး"</string>
+    <string name="category_work" msgid="8699184680584175622">"အလုပ်အကိုင်"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 5e83f92..413165a 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> støttes fullt ut"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> krever nettverkstilkobling"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> støttes ikke"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Kontrollerer …"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Innstillinger for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Innstillinger for kjøring av motor"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Foretrukket motor"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Generelt"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Veldig langsom"</item>
+    <item msgid="4795095314303559268">"Langsom"</item>
+    <item msgid="8903157781070679765">"Vanlig"</item>
+    <item msgid="164347302621392996">"Rask"</item>
+    <item msgid="5794028588101562009">"Litt raskere"</item>
+    <item msgid="7163942783888652942">"Veldig rask"</item>
+    <item msgid="7831712693748700507">"Hurtig"</item>
+    <item msgid="5194774745031751806">"Veldig hurtig"</item>
+    <item msgid="9085102246155045744">"Raskest"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Velg profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personlig"</string>
+    <string name="category_work" msgid="8699184680584175622">"Jobb"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index 56c68d2..eedbdec 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> पूर्ण रूपले समर्थित छ"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> नेटवर्क जडान चाहिन्छ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> समर्थित छैन"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"जाँच गर्दै..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>को लागि सेटिङ गर्दै"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"इन्जिन सेटिङहरू सुरुवात गर्नुहोस्"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"रुचाइएको इन्जिन"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"सामान्य"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"निकै बिस्तारै"</item>
+    <item msgid="4795095314303559268">"ढिलो"</item>
+    <item msgid="8903157781070679765">"सामान्य"</item>
+    <item msgid="164347302621392996">"छिटो"</item>
+    <item msgid="5794028588101562009">"थप छिटो"</item>
+    <item msgid="7163942783888652942">"ज्यादै छिटो"</item>
+    <item msgid="7831712693748700507">"तीव्र"</item>
+    <item msgid="5194774745031751806">"धेरै तीव्र"</item>
+    <item msgid="9085102246155045744">"सबभन्दा छिटो"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"प्रोफाइल रोज्नुहोस्"</string>
+    <string name="category_personal" msgid="1299663247844969448">"व्यक्तिगत"</string>
+    <string name="category_work" msgid="8699184680584175622">"काम"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 7e07a40..d2edbb7 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Zeer vlug"</item>
     <item msgid="9085102246155045744">"Snelst"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profiel kiezen"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Persoonlijk"</string>
+    <string name="category_work" msgid="8699184680584175622">"Werk"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index c21185b..921d48f 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ਪੂਰੀ ਤਰ੍ਹਾਂ ਸਮਰਥਿਤ ਹੈ"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ਲਈ ਨੈਟਵਰਕ ਕਨੈਕਸ਼ਨ ਲੁੜੀਂਦਾ ਹੈ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"ਜਾਂਚ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> ਲਈ ਸੈਟਿੰਗਾਂ"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"ਇੰਜਨ ਸੈਟਿੰਗਾਂ ਲੌਂਚ ਕਰੋ"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ਤਰਜੀਹੀ ਇੰਜਣ"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"ਸਧਾਰਨ"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ਬਹੁਤ ਹੌਲੀ"</item>
+    <item msgid="4795095314303559268">"ਹੌਲੀ"</item>
+    <item msgid="8903157781070679765">"ਸਧਾਰਨ"</item>
+    <item msgid="164347302621392996">"ਤੇਜ਼"</item>
+    <item msgid="5794028588101562009">"ਵੱਧ ਤੇਜ਼"</item>
+    <item msgid="7163942783888652942">"ਬਹੁਤ ਤੇਜ਼"</item>
+    <item msgid="7831712693748700507">"ਤੇਜ਼"</item>
+    <item msgid="5194774745031751806">"ਬਹੁਤ ਤੇਜ਼"</item>
+    <item msgid="9085102246155045744">"ਸਭ ਤੋਂ ਵੱਧ ਤੇਜ਼"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ਨਿੱਜੀ"</string>
+    <string name="category_work" msgid="8699184680584175622">"ਦਫ਼ਤਰ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index b560d9d..8fa5abf 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Język <xliff:g id="LOCALE">%1$s</xliff:g> jest w pełni obsługiwany"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Język <xliff:g id="LOCALE">%1$s</xliff:g> wymaga połączenia z siecią"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Język <xliff:g id="LOCALE">%1$s</xliff:g> nie jest obsługiwany"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Sprawdzam…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Ustawienia <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Otwórz ustawienia mechanizmu"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferowany mechanizm"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Ogólne"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Bardzo wolno"</item>
+    <item msgid="4795095314303559268">"Powoli"</item>
+    <item msgid="8903157781070679765">"Normalnie"</item>
+    <item msgid="164347302621392996">"Szybko"</item>
+    <item msgid="5794028588101562009">"Trochę szybciej"</item>
+    <item msgid="7163942783888652942">"Szybciej"</item>
+    <item msgid="7831712693748700507">"Jeszcze szybciej"</item>
+    <item msgid="5194774745031751806">"Bardzo szybko"</item>
+    <item msgid="9085102246155045744">"Najszybciej"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Wybierz profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Osobiste"</string>
+    <string name="category_work" msgid="8699184680584175622">"Praca"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 91ba0b5..4dd6961 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportada"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requer conexão de rede"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> não é suportado"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Verificando..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Configurações para <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Iniciar configurações do mecanismo"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Mecanismo preferencial"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Gerais"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Muito devagar"</item>
+    <item msgid="4795095314303559268">"Devagar"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Rápida"</item>
+    <item msgid="5794028588101562009">"Mais rápida"</item>
+    <item msgid="7163942783888652942">"Muito rápida"</item>
+    <item msgid="7831712693748700507">"Rápida"</item>
+    <item msgid="5194774745031751806">"Muito rápida"</item>
+    <item msgid="9085102246155045744">"Super-rápida"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Pessoal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Trabalho"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 2d831d1..1a54edb 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportado"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> necessita de ligação de rede"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> não é suportado"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"A verificar…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Definições do <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Iniciar as definições do motor"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor preferido"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Geral"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Muito lenta"</item>
+    <item msgid="4795095314303559268">"Lenta"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Rápida"</item>
+    <item msgid="5794028588101562009">"Mais rápida"</item>
+    <item msgid="7163942783888652942">"Muito rápida"</item>
+    <item msgid="7831712693748700507">"Acelerada"</item>
+    <item msgid="5194774745031751806">"Muito acelerada"</item>
+    <item msgid="9085102246155045744">"A mais rápida"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Pessoal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Trabalho"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 91ba0b5..4dd6961 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> é totalmente suportada"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requer conexão de rede"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> não é suportado"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Verificando..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Configurações para <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Iniciar configurações do mecanismo"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Mecanismo preferencial"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Gerais"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Muito devagar"</item>
+    <item msgid="4795095314303559268">"Devagar"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Rápida"</item>
+    <item msgid="5794028588101562009">"Mais rápida"</item>
+    <item msgid="7163942783888652942">"Muito rápida"</item>
+    <item msgid="7831712693748700507">"Rápida"</item>
+    <item msgid="5194774745031751806">"Muito rápida"</item>
+    <item msgid="9085102246155045744">"Super-rápida"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Escolher perfil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Pessoal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Trabalho"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 74f98e0..262fe97 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> este acceptată integral"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> necesită conexiune la rețea"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> nu este acceptată"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Se verifică…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Setări pentru <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Lansați setările motorului"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor preferat"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Preferințe generale"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Foarte încet"</item>
+    <item msgid="4795095314303559268">"Încet"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Repede"</item>
+    <item msgid="5794028588101562009">"Mai repede"</item>
+    <item msgid="7163942783888652942">"Foarte repede"</item>
+    <item msgid="7831712693748700507">"Rapid"</item>
+    <item msgid="5194774745031751806">"Foarte rapid"</item>
+    <item msgid="9085102246155045744">"Cel mai repede"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Alegeți un profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Serviciu"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index d116a3b..31b70ad 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> поддерживается"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> поддерживается только при подключении к сети"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> не поддерживается"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Проверка…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Настройки синтеза речи"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Система по умолчанию"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Общие"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Очень медленная"</item>
+    <item msgid="4795095314303559268">"Медленная"</item>
+    <item msgid="8903157781070679765">"Обычная"</item>
+    <item msgid="164347302621392996">"Умеренно быстрая"</item>
+    <item msgid="5794028588101562009">"Быстрая"</item>
+    <item msgid="7163942783888652942">"Очень быстрая"</item>
+    <item msgid="7831712693748700507">"Ускоренная"</item>
+    <item msgid="5194774745031751806">"Сильно ускоренная"</item>
+    <item msgid="9085102246155045744">"Максимальная"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Выберите профиль"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Личные данные"</string>
+    <string name="category_work" msgid="8699184680584175622">"Работа"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index 5fe0863..6ff81b7 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> මුළුමනින්ම සහාය දක්වයි"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> සඳහා ජාල සම්බන්ධතාවයක් අවශ්‍යයි"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> සහාය නොදක්වයි"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"පරික්ෂා කරමින්..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> සඳහා සැකසුම්"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"එන්ජිම් සැකසීම් දියත් කරන්න"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"වරණ එන්ජිම"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"සාමාන්‍ය"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ඉතා මන්දගාමී"</item>
+    <item msgid="4795095314303559268">"මන්දගාමී"</item>
+    <item msgid="8903157781070679765">"සාමාන්‍ය"</item>
+    <item msgid="164347302621392996">"වේගවත්"</item>
+    <item msgid="5794028588101562009">"වේශවත්"</item>
+    <item msgid="7163942783888652942">"ඉතා වේගවත්"</item>
+    <item msgid="7831712693748700507">"ශීඝ්‍ර"</item>
+    <item msgid="5194774745031751806">"ඉතා ශීඝ්‍ර"</item>
+    <item msgid="9085102246155045744">"ඉතාම වේගවත්"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"පැතිකඩ තෝරන්න"</string>
+    <string name="category_personal" msgid="1299663247844969448">"පෞද්ගලික"</string>
+    <string name="category_work" msgid="8699184680584175622">"කාර්යාලය"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 7499fea..a499dc5 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Jazyk <xliff:g id="LOCALE">%1$s</xliff:g> je plne podporovaný"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Jazyk <xliff:g id="LOCALE">%1$s</xliff:g> vyžaduje pripojenie k sieti"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Jazyk <xliff:g id="LOCALE">%1$s</xliff:g> nie je podporovaný"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Kontroluje sa..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Spustiť nastavenia nástroja"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferovaný nástroj"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Všeobecné"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Veľmi pomaly"</item>
+    <item msgid="4795095314303559268">"Pomaly"</item>
+    <item msgid="8903157781070679765">"Normálne"</item>
+    <item msgid="164347302621392996">"Rýchlo"</item>
+    <item msgid="5794028588101562009">"Rýchlejšie"</item>
+    <item msgid="7163942783888652942">"Veľmi rýchlo"</item>
+    <item msgid="7831712693748700507">"Svižne"</item>
+    <item msgid="5194774745031751806">"Veľmi rýchlo"</item>
+    <item msgid="9085102246155045744">"Najrýchlejšie"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Výber profilu"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Osobné"</string>
+    <string name="category_work" msgid="8699184680584175622">"Práca"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 294e9bb..b2d047b 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Jezik <xliff:g id="LOCALE">%1$s</xliff:g> je v celoti podprt"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> zahteva omrežno povezavo"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Jezik <xliff:g id="LOCALE">%1$s</xliff:g> ni podprt"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Preverjanje ..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Nastavitve za <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Zagon nastavitev mehanizma"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Prednostni mehanizem"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Splošno"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Zelo počasi"</item>
+    <item msgid="4795095314303559268">"Počasi"</item>
+    <item msgid="8903157781070679765">"Običajno"</item>
+    <item msgid="164347302621392996">"Hitro"</item>
+    <item msgid="5794028588101562009">"Hitreje"</item>
+    <item msgid="7163942783888652942">"Zelo hitro"</item>
+    <item msgid="7831712693748700507">"Naglo"</item>
+    <item msgid="5194774745031751806">"Zelo naglo"</item>
+    <item msgid="9085102246155045744">"Najhitreje"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Izbira profila"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Osebno"</string>
+    <string name="category_work" msgid="8699184680584175622">"Služba"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index 609dce2..87390b4 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> mbështetet plotësisht"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> kërkon lidhje interneti"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> nuk mbështetet"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Po kontrollon..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Cilësimet për \"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>\""</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Hap cilësimet e motorit"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motori i preferuar"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Të përgjithshme"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Shumë e ulët"</item>
+    <item msgid="4795095314303559268">"E ngadaltë"</item>
+    <item msgid="8903157781070679765">"Normale"</item>
+    <item msgid="164347302621392996">"E shpejtë"</item>
+    <item msgid="5794028588101562009">"Më e shpejtë"</item>
+    <item msgid="7163942783888652942">"Shumë e shpejtë"</item>
+    <item msgid="7831712693748700507">"E shpejtë"</item>
+    <item msgid="5194774745031751806">"Shumë e shpejtë"</item>
+    <item msgid="9085102246155045744">"Më e shpejta"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Zgjidh profilin"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personale"</string>
+    <string name="category_work" msgid="8699184680584175622">"Punë"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 3f7d1fa..4ed4739 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> је подржан у потпуности"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> захтева везу са мрежом"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> није подржан"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Проверава се..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Подешавања за <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Покрени подешавања машине"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Жељена машина"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Опште"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Веома споро"</item>
+    <item msgid="4795095314303559268">"Споро"</item>
+    <item msgid="8903157781070679765">"Нормално"</item>
+    <item msgid="164347302621392996">"Брзо"</item>
+    <item msgid="5794028588101562009">"Брже"</item>
+    <item msgid="7163942783888652942">"Веома брзо"</item>
+    <item msgid="7831712693748700507">"Убрзано"</item>
+    <item msgid="5194774745031751806">"Веома убрзано"</item>
+    <item msgid="9085102246155045744">"Најбрже"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Изаберите профил"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Лично"</string>
+    <string name="category_work" msgid="8699184680584175622">"Посао"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index d3d5279..1db99a59 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> stöds"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> kräver nätverksanslutning"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> stöds inte"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Kontrollerar …"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Inställningar för <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Öppna inställningar för sökmotor"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Prioriterad sökmotor"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Allmänt"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Mycket långsamt"</item>
+    <item msgid="4795095314303559268">"Långsamt"</item>
+    <item msgid="8903157781070679765">"Normalt"</item>
+    <item msgid="164347302621392996">"Snabbt"</item>
+    <item msgid="5794028588101562009">"Snabbare"</item>
+    <item msgid="7163942783888652942">"Mycket snabbt"</item>
+    <item msgid="7831712693748700507">"Supersnabbt"</item>
+    <item msgid="5194774745031751806">"Turbosnabbt"</item>
+    <item msgid="9085102246155045744">"Snabbast"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Välj profil"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personligt"</string>
+    <string name="category_work" msgid="8699184680584175622">"Arbetet"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 13c3790..e4740ac 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> inaweza kutumiwa kikamilifu"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> inahitaji muunganisho wa mtandao"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> haiwezi kutumiwa"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Inakagua..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Mipangilio ya <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Zindua mipangilio ya injini"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Injini inayofaa"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Kwa ujumla"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Polepole sana"</item>
+    <item msgid="4795095314303559268">"Polepole"</item>
+    <item msgid="8903157781070679765">"Kawaida"</item>
+    <item msgid="164347302621392996">"Haraka"</item>
+    <item msgid="5794028588101562009">"Haraka kiasi"</item>
+    <item msgid="7163942783888652942">"Haraka sana"</item>
+    <item msgid="7831712693748700507">"Kasi"</item>
+    <item msgid="5194774745031751806">"Kasi sana"</item>
+    <item msgid="9085102246155045744">"Kasi zaidi"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Chagua Wasifu"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Ya Kibinafsi"</string>
+    <string name="category_work" msgid="8699184680584175622">"Kazini"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index 26ead85..aaafa68 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> முழுமையாக ஆதரிக்கப்படுகிறது"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> க்கு நெட்வொர்க் இணைப்பு அவசியமாகும்"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ஆதரிக்கப்படவில்லை"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"சரிபார்க்கிறது..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> க்கான அமைப்பு"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"இன்ஜின் அமைப்புகளைத் தொடங்கு"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"விருப்பத்தேர்வு"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"பொதுவானவை"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"மிகவும் மெதுவாக"</item>
+    <item msgid="4795095314303559268">"மெதுவாக"</item>
+    <item msgid="8903157781070679765">"இயல்பு"</item>
+    <item msgid="164347302621392996">"வேகமாக"</item>
+    <item msgid="5794028588101562009">"மிக வேகமாக"</item>
+    <item msgid="7163942783888652942">"அதிவேகமாக"</item>
+    <item msgid="7831712693748700507">"அதிக வேகமாக"</item>
+    <item msgid="5194774745031751806">"மிக அதிக வேகமாக"</item>
+    <item msgid="9085102246155045744">"அதிகபட்ச வேகம்"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"சுயவிவரத்தைத் தேர்வுசெய்யவும்"</string>
+    <string name="category_personal" msgid="1299663247844969448">"தனிப்பட்டவை"</string>
+    <string name="category_work" msgid="8699184680584175622">"பணியிடம்"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index e5f6509..4b3570e 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g>కి పూర్తి మద్దతు ఉంది"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g>కి నెట్‌వర్క్ కనెక్షన్ అవసరం"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g>కు మద్దతు లేదు"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"తనిఖీ చేస్తోంది..."</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> కోసం సెట్టింగ్‌లు"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"ఇంజిన్ సెట్టింగ్‌లను ప్రారంభించండి"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ప్రాధాన్య ఇంజిన్"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"సాధారణం"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"చాలా నెమ్మది"</item>
+    <item msgid="4795095314303559268">"నెమ్మది"</item>
+    <item msgid="8903157781070679765">"సాధారణం"</item>
+    <item msgid="164347302621392996">"వేగవంతం"</item>
+    <item msgid="5794028588101562009">"అధిక వేగవంతం"</item>
+    <item msgid="7163942783888652942">"చాలా వేగవంతం"</item>
+    <item msgid="7831712693748700507">"అధిక వేగం"</item>
+    <item msgid="5194774745031751806">"అత్యంత వేగం"</item>
+    <item msgid="9085102246155045744">"అత్యంత వేగవంతం"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"ప్రొఫైల్‌ను ఎంచుకోండి"</string>
+    <string name="category_personal" msgid="1299663247844969448">"వ్యక్తిగతం"</string>
+    <string name="category_work" msgid="8699184680584175622">"కార్యాలయం"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 529d10f..029962e 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"สนับสนุน<xliff:g id="LOCALE">%1$s</xliff:g>อย่างสมบูรณ์"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"ต้องมีการเชื่อมต่อเครือข่ายสำหรับ<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"ไม่สนับสนุน<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"กำลังตรวจสอบ…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"การตั้งค่าสำหรับ <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"เปิดการตั้งค่าเครื่องมือ"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"เครื่องมือที่ต้องการ"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"ทั่วไป"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ช้ามาก"</item>
+    <item msgid="4795095314303559268">"ช้า"</item>
+    <item msgid="8903157781070679765">"ปกติ"</item>
+    <item msgid="164347302621392996">"เร็ว"</item>
+    <item msgid="5794028588101562009">"เร็วขึ้น"</item>
+    <item msgid="7163942783888652942">"เร็วมาก"</item>
+    <item msgid="7831712693748700507">"เร็ว"</item>
+    <item msgid="5194774745031751806">"เร็วมาก"</item>
+    <item msgid="9085102246155045744">"เร็วที่สุด"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"เลือกโปรไฟล์"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ส่วนตัว"</string>
+    <string name="category_work" msgid="8699184680584175622">"ที่ทำงาน"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 2102748..49f10a9 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"Ganap na sinusuportahan ang <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"Kailangan ng <xliff:g id="LOCALE">%1$s</xliff:g> ng koneksyon sa network"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"Hindi sinusuportahan ang <xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Sinusuri…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Mga setting para sa <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Ilunsad ang mga setting ng engine"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Ginustong engine"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Pangkalahatan"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Napakabagal"</item>
+    <item msgid="4795095314303559268">"Mabagal"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Mabilis"</item>
+    <item msgid="5794028588101562009">"Mas Mabilis"</item>
+    <item msgid="7163942783888652942">"Napakabilis"</item>
+    <item msgid="7831712693748700507">"Matulin"</item>
+    <item msgid="5194774745031751806">"Napakatulin"</item>
+    <item msgid="9085102246155045744">"Pinakamabilis"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Pumili ng Profile"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+    <string name="category_work" msgid="8699184680584175622">"Trabaho"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 67eed9d..db40231 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> tamamen destekleniyor"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ağ bağlantısı gerektiriyor"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> desteklenmiyor"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Kontrol ediliyor…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> ayarları"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Motor ayarlarını başlat"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Tercih edilen motor"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Genel"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Çok yavaş"</item>
+    <item msgid="4795095314303559268">"Yavaş"</item>
+    <item msgid="8903157781070679765">"Normal"</item>
+    <item msgid="164347302621392996">"Hızlı"</item>
+    <item msgid="5794028588101562009">"Daha hızlı"</item>
+    <item msgid="7163942783888652942">"Çok hızlı"</item>
+    <item msgid="7831712693748700507">"Seri"</item>
+    <item msgid="5194774745031751806">"Çok seri"</item>
+    <item msgid="9085102246155045744">"En hızlı"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profil Seçin"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Kişisel"</string>
+    <string name="category_work" msgid="8699184680584175622">"İş"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 231b89b0..696ea39 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Украй швидко"</item>
     <item msgid="9085102246155045744">"Найшвидше"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Вибрати профіль"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Особисте"</string>
+    <string name="category_work" msgid="8699184680584175622">"Робота"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index 788c959..31b76ed 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> مکمل طور پر تعاون یافتہ ہے"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> کو نیٹ ورک کنکشن کی ضرورت ہے"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> تعاون یافتہ نہیں ہے"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"چیک کیا جا رہا ہے…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> کیلئے ترتیبات"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"انجن کی ترتیبات شروع کریں"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ترجیحی انجن"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"عمومی"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"بہت سست"</item>
+    <item msgid="4795095314303559268">"سست"</item>
+    <item msgid="8903157781070679765">"عام"</item>
+    <item msgid="164347302621392996">"تیز"</item>
+    <item msgid="5794028588101562009">"تیز تر"</item>
+    <item msgid="7163942783888652942">"بہت تیز"</item>
+    <item msgid="7831712693748700507">"تیز"</item>
+    <item msgid="5194774745031751806">"کافی تیز"</item>
+    <item msgid="9085102246155045744">"تیز ترین"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"پروفائل منتخب کریں"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ذاتی"</string>
+    <string name="category_work" msgid="8699184680584175622">"دفتر"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index a02d236..705194c 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> – to‘liq qo‘llab-quvvatlanadi"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> tili tarmoqqa ulanishi lozim"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> – qo‘llab-quvvatlanmaydi"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Tekshirilmoqda…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> sozlamalari"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Mexanizm sozlamalarini ishga tushirish"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Standart tizim"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Umumiy"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Juda sekin"</item>
+    <item msgid="4795095314303559268">"Sekin"</item>
+    <item msgid="8903157781070679765">"O‘rtacha"</item>
+    <item msgid="164347302621392996">"Tez"</item>
+    <item msgid="5794028588101562009">"Tezroq"</item>
+    <item msgid="7163942783888652942">"Juda tez"</item>
+    <item msgid="7831712693748700507">"Tez"</item>
+    <item msgid="5194774745031751806">"Juda tez"</item>
+    <item msgid="9085102246155045744">"Eng tez"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Profil tanlash"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Shaxsiy"</string>
+    <string name="category_work" msgid="8699184680584175622">"Ish"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 95451a8..c3db6c5 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> được hỗ trợ đầy đủ"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> yêu cầu kết nối mạng"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> không được hỗ trợ"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"Đang kiểm tra…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"Cài đặt cho <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"Cài đặt chạy công cụ"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Công cụ ưu tiên"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Chung"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"Rất chậm"</item>
+    <item msgid="4795095314303559268">"Chậm"</item>
+    <item msgid="8903157781070679765">"Bình thường"</item>
+    <item msgid="164347302621392996">"Nhanh"</item>
+    <item msgid="5794028588101562009">"Nhanh hơn"</item>
+    <item msgid="7163942783888652942">"Rất nhanh"</item>
+    <item msgid="7831712693748700507">"Nhanh"</item>
+    <item msgid="5194774745031751806">"Rất nhanh"</item>
+    <item msgid="9085102246155045744">"Nhanh nhất"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Chọn hồ sơ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Cá nhân"</string>
+    <string name="category_work" msgid="8699184680584175622">"Cơ quan"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 5ca95da3..e7c6d14 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"完全支持<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"只有在连接到网络的情况下,才支持<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"不支持<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"正在检查…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"“<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>”的设置"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"进行引擎设置"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"首选引擎"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"常规"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"很慢"</item>
+    <item msgid="4795095314303559268">"慢"</item>
+    <item msgid="8903157781070679765">"正常"</item>
+    <item msgid="164347302621392996">"快"</item>
+    <item msgid="5794028588101562009">"较快"</item>
+    <item msgid="7163942783888652942">"非常快"</item>
+    <item msgid="7831712693748700507">"迅速"</item>
+    <item msgid="5194774745031751806">"很迅速"</item>
+    <item msgid="9085102246155045744">"最快"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"选择个人资料"</string>
+    <string name="category_personal" msgid="1299663247844969448">"个人"</string>
+    <string name="category_work" msgid="8699184680584175622">"工作"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index d6bd3c3..170bc0f 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"極快"</item>
     <item msgid="9085102246155045744">"最快"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"選擇設定檔"</string>
+    <string name="category_personal" msgid="1299663247844969448">"個人"</string>
+    <string name="category_work" msgid="8699184680584175622">"公司"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 94be638..8a00d8c 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -116,19 +116,23 @@
     <string name="tts_status_ok" msgid="1309762510278029765">"完整支援<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"需要網路連線才支援<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"不支援<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
-    <!-- no translation found for tts_status_checking (5339150797940483592) -->
-    <skip />
+    <string name="tts_status_checking" msgid="5339150797940483592">"檢查中…"</string>
     <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> 設定"</string>
     <string name="tts_engine_settings_button" msgid="1030512042040722285">"啟動引擎設定"</string>
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"偏好的引擎"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"一般"</string>
-    <!-- no translation found for tts_rate_entries:0 (6695494874362656215) -->
-    <!-- no translation found for tts_rate_entries:1 (4795095314303559268) -->
-    <!-- no translation found for tts_rate_entries:2 (8903157781070679765) -->
-    <!-- no translation found for tts_rate_entries:3 (164347302621392996) -->
-    <!-- no translation found for tts_rate_entries:4 (5794028588101562009) -->
-    <!-- no translation found for tts_rate_entries:5 (7163942783888652942) -->
-    <!-- no translation found for tts_rate_entries:6 (7831712693748700507) -->
-    <!-- no translation found for tts_rate_entries:7 (5194774745031751806) -->
-    <!-- no translation found for tts_rate_entries:8 (9085102246155045744) -->
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"很慢"</item>
+    <item msgid="4795095314303559268">"慢"</item>
+    <item msgid="8903157781070679765">"一般"</item>
+    <item msgid="164347302621392996">"快"</item>
+    <item msgid="5794028588101562009">"較快"</item>
+    <item msgid="7163942783888652942">"很快"</item>
+    <item msgid="7831712693748700507">"非常快"</item>
+    <item msgid="5194774745031751806">"極快"</item>
+    <item msgid="9085102246155045744">"最快"</item>
+  </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"選擇設定檔"</string>
+    <string name="category_personal" msgid="1299663247844969448">"個人"</string>
+    <string name="category_work" msgid="8699184680584175622">"公司"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index a092a17..4575ac1 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -132,4 +132,7 @@
     <item msgid="5194774745031751806">"Esheshisa kakhulu"</item>
     <item msgid="9085102246155045744">"Esheshisa kakhulukhulu"</item>
   </string-array>
+    <string name="choose_profile" msgid="8229363046053568878">"Khetha iphrofayela"</string>
+    <string name="category_personal" msgid="1299663247844969448">"Okomuntu siqu"</string>
+    <string name="category_work" msgid="8699184680584175622">"Umsebenzi"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 9e48849..a37196e 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -348,4 +348,7 @@
     <!-- Header for items under the work user [CHAR LIMIT=30] -->
     <string name="category_work">Work</string>
 
+    <!-- Full package name of OEM preferred device feedback reporter. Leave this blank, overlaid in Settings/TvSettings [DO NOT TRANSLATE] -->
+    <string name="oem_preferred_feedback_reporter" translatable="false" />
+
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
new file mode 100644
index 0000000..ff1c866
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
@@ -0,0 +1,172 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Build;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DeviceInfoUtils {
+    private static final String TAG = "DeviceInfoUtils";
+
+    private static final String FILENAME_PROC_VERSION = "/proc/version";
+    private static final String FILENAME_MSV = "/sys/board_properties/soc/msv";
+
+    /**
+     * Reads a line from the specified file.
+     * @param filename the file to read from
+     * @return the first line, if any.
+     * @throws IOException if the file couldn't be read
+     */
+    private static String readLine(String filename) throws IOException {
+        BufferedReader reader = new BufferedReader(new FileReader(filename), 256);
+        try {
+            return reader.readLine();
+        } finally {
+            reader.close();
+        }
+    }
+
+    public static String getFormattedKernelVersion() {
+        try {
+            return formatKernelVersion(readLine(FILENAME_PROC_VERSION));
+        } catch (IOException e) {
+            Log.e(TAG, "IO Exception when getting kernel version for Device Info screen",
+                    e);
+
+            return "Unavailable";
+        }
+    }
+
+    public static String formatKernelVersion(String rawKernelVersion) {
+        // Example (see tests for more):
+        // Linux version 3.0.31-g6fb96c9 (android-build@xxx.xxx.xxx.xxx.com) \
+        //     (gcc version 4.6.x-xxx 20120106 (prerelease) (GCC) ) #1 SMP PREEMPT \
+        //     Thu Jun 28 11:02:39 PDT 2012
+
+        final String PROC_VERSION_REGEX =
+                "Linux version (\\S+) " + /* group 1: "3.0.31-g6fb96c9" */
+                "\\((\\S+?)\\) " +        /* group 2: "x@y.com" (kernel builder) */
+                "(?:\\(gcc.+? \\)) " +    /* ignore: GCC version information */
+                "(#\\d+) " +              /* group 3: "#1" */
+                "(?:.*?)?" +              /* ignore: optional SMP, PREEMPT, and any CONFIG_FLAGS */
+                "((Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)"; /* group 4: "Thu Jun 28 11:02:39 PDT 2012" */
+
+        Matcher m = Pattern.compile(PROC_VERSION_REGEX).matcher(rawKernelVersion);
+        if (!m.matches()) {
+            Log.e(TAG, "Regex did not match on /proc/version: " + rawKernelVersion);
+            return "Unavailable";
+        } else if (m.groupCount() < 4) {
+            Log.e(TAG, "Regex match on /proc/version only returned " + m.groupCount()
+                    + " groups");
+            return "Unavailable";
+        }
+        return m.group(1) + "\n" +                 // 3.0.31-g6fb96c9
+                m.group(2) + " " + m.group(3) + "\n" + // x@y.com #1
+                m.group(4);                            // Thu Jun 28 11:02:39 PDT 2012
+    }
+
+    /**
+     * Returns " (ENGINEERING)" if the msv file has a zero value, else returns "".
+     * @return a string to append to the model number description.
+     */
+    public static String getMsvSuffix() {
+        // Production devices should have a non-zero value. If we can't read it, assume it's a
+        // production device so that we don't accidentally show that it's an ENGINEERING device.
+        try {
+            String msv = readLine(FILENAME_MSV);
+            // Parse as a hex number. If it evaluates to a zero, then it's an engineering build.
+            if (Long.parseLong(msv, 16) == 0) {
+                return " (ENGINEERING)";
+            }
+        } catch (IOException|NumberFormatException e) {
+            // Fail quietly, as the file may not exist on some devices, or may be unreadable
+        }
+        return "";
+    }
+
+    public static String getFeedbackReporterPackage(Context context) {
+        final String feedbackReporter =
+                context.getResources().getString(R.string.oem_preferred_feedback_reporter);
+        if (TextUtils.isEmpty(feedbackReporter)) {
+            // Reporter not configured. Return.
+            return feedbackReporter;
+        }
+        // Additional checks to ensure the reporter is on system image, and reporter is
+        // configured to listen to the intent. Otherwise, dont show the "send feedback" option.
+        final Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
+
+        PackageManager pm = context.getPackageManager();
+        List<ResolveInfo> resolvedPackages =
+                pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
+        for (ResolveInfo info : resolvedPackages) {
+            if (info.activityInfo != null) {
+                if (!TextUtils.isEmpty(info.activityInfo.packageName)) {
+                    try {
+                        ApplicationInfo ai =
+                                pm.getApplicationInfo(info.activityInfo.packageName, 0);
+                        if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                            // Package is on the system image
+                            if (TextUtils.equals(
+                                    info.activityInfo.packageName, feedbackReporter)) {
+                                return feedbackReporter;
+                            }
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                        // No need to do anything here.
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public static String getSecurityPatch() {
+        String patch = Build.VERSION.SECURITY_PATCH;
+        if (!"".equals(patch)) {
+            try {
+                SimpleDateFormat template = new SimpleDateFormat("yyyy-MM-dd");
+                Date patchDate = template.parse(patch);
+                String format = DateFormat.getBestDateTimePattern(Locale.getDefault(), "dMMMMyyyy");
+                patch = DateFormat.format(format, patchDate).toString();
+            } catch (ParseException e) {
+                // broken parse; fall through and use the raw string
+            }
+            return patch;
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index e4b1ed8..d994841 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -808,7 +808,12 @@
             // The pairing dialog now warns of phone-book access for paired devices.
             // No separate prompt is displayed after pairing.
             if (getPhonebookPermissionChoice() == CachedBluetoothDevice.ACCESS_UNKNOWN) {
-                setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_ALLOWED);
+                if (mDevice.getBluetoothClass().getDeviceClass()
+                        == BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE) {
+                    setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_ALLOWED);
+                } else {
+                    setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_REJECTED);
+                }
             }
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index 910e615..6102bef 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -18,6 +18,7 @@
 import android.annotation.LayoutRes;
 import android.annotation.Nullable;
 import android.app.Activity;
+import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.support.v4.widget.DrawerLayout;
 import android.util.Pair;
@@ -50,8 +51,17 @@
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         super.setContentView(R.layout.settings_with_drawer);
         mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
-        // Nope.
+        if (mDrawerLayout == null) {
+            return;
+        }
         Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar);
+        TypedArray theme = getTheme().obtainStyledAttributes(android.R.styleable.Theme);
+        if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
+            toolbar.setVisibility(View.GONE);
+            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+            mDrawerLayout = null;
+            return;
+        }
         setActionBar(toolbar);
         mDrawerAdapter = new SettingsDrawerAdapter(this);
         ListView listView = (ListView) findViewById(R.id.left_drawer);
@@ -62,12 +72,12 @@
                 onTileClicked(mDrawerAdapter.getTile(position));
             };
         });
-        getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        if (item.getItemId() == android.R.id.home) {
+        if (mDrawerLayout != null && item.getItemId() == android.R.id.home
+                && mDrawerAdapter.getCount() != 0) {
             openDrawer();
             return true;
         }
@@ -78,15 +88,19 @@
     protected void onResume() {
         super.onResume();
 
-        mDrawerAdapter.updateCategories();
+        updateDrawer();
     }
 
     public void openDrawer() {
-        mDrawerLayout.openDrawer(Gravity.START);
+        if (mDrawerLayout != null) {
+            mDrawerLayout.openDrawer(Gravity.START);
+        }
     }
 
     public void closeDrawer() {
-        mDrawerLayout.closeDrawers();
+        if (mDrawerLayout != null) {
+            mDrawerLayout.closeDrawers();
+        }
     }
 
     @Override
@@ -106,9 +120,18 @@
     }
 
     public void updateDrawer() {
+        if (mDrawerLayout == null) {
+            return;
+        }
         // TODO: Do this in the background with some loading.
         mDrawerAdapter.updateCategories();
-        getActionBar().setDisplayHomeAsUpEnabled(mDrawerAdapter.getCount() != 0);
+        if (mDrawerAdapter.getCount() != 0) {
+            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
+            getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
+            getActionBar().setDisplayHomeAsUpEnabled(true);
+        } else {
+            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+        }
     }
 
     public List<DashboardCategory> getDashboardCategories(boolean force) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
new file mode 100644
index 0000000..f03e94d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -0,0 +1,185 @@
+/*
+ * 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.location;
+
+import android.app.AppGlobals;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Retrieves the information of applications which accessed location recently.
+ */
+public class RecentLocationApps {
+    private static final String TAG = RecentLocationApps.class.getSimpleName();
+    private static final String ANDROID_SYSTEM_PACKAGE_NAME = "android";
+
+    private static final int RECENT_TIME_INTERVAL_MILLIS = 15 * 60 * 1000;
+
+    private static final int[] LOCATION_OPS = new int[] {
+            AppOpsManager.OP_MONITOR_LOCATION,
+            AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION,
+    };
+
+    private final PackageManager mPackageManager;
+    private final Context mContext;
+
+    public RecentLocationApps(Context context) {
+        mContext = context;
+        mPackageManager = context.getPackageManager();
+    }
+
+    /**
+     * Fills a list of applications which queried location recently within specified time.
+     */
+    public List<Request> getAppList() {
+        // Retrieve a location usage list from AppOps
+        AppOpsManager aoManager =
+                (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        List<AppOpsManager.PackageOps> appOps = aoManager.getPackagesForOps(LOCATION_OPS);
+
+        // Process the AppOps list and generate a preference list.
+        ArrayList<Request> requests = new ArrayList<>(appOps.size());
+        final long now = System.currentTimeMillis();
+        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        final List<UserHandle> profiles = um.getUserProfiles();
+
+        final int appOpsN = appOps.size();
+        for (int i = 0; i < appOpsN; ++i) {
+            AppOpsManager.PackageOps ops = appOps.get(i);
+            // Don't show the Android System in the list - it's not actionable for the user.
+            // Also don't show apps belonging to background users except managed users.
+            String packageName = ops.getPackageName();
+            int uid = ops.getUid();
+            int userId = UserHandle.getUserId(uid);
+            boolean isAndroidOs =
+                    (uid == Process.SYSTEM_UID) && ANDROID_SYSTEM_PACKAGE_NAME.equals(packageName);
+            if (isAndroidOs || !profiles.contains(new UserHandle(userId))) {
+                continue;
+            }
+            Request request = getRequestFromOps(now, ops);
+            if (request != null) {
+                requests.add(request);
+            }
+        }
+
+        return requests;
+    }
+
+    /**
+     * Creates a Request entry for the given PackageOps.
+     *
+     * This method examines the time interval of the PackageOps first. If the PackageOps is older
+     * than the designated interval, this method ignores the PackageOps object and returns null.
+     * When the PackageOps is fresh enough, this method returns a Request object for the package
+     */
+    private Request getRequestFromOps(long now,
+            AppOpsManager.PackageOps ops) {
+        String packageName = ops.getPackageName();
+        List<AppOpsManager.OpEntry> entries = ops.getOps();
+        boolean highBattery = false;
+        boolean normalBattery = false;
+        // Earliest time for a location request to end and still be shown in list.
+        long recentLocationCutoffTime = now - RECENT_TIME_INTERVAL_MILLIS;
+        for (AppOpsManager.OpEntry entry : entries) {
+            if (entry.isRunning() || entry.getTime() >= recentLocationCutoffTime) {
+                switch (entry.getOp()) {
+                    case AppOpsManager.OP_MONITOR_LOCATION:
+                        normalBattery = true;
+                        break;
+                    case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION:
+                        highBattery = true;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        if (!highBattery && !normalBattery) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, packageName + " hadn't used location within the time interval.");
+            }
+            return null;
+        }
+
+        // The package is fresh enough, continue.
+
+        int uid = ops.getUid();
+        int userId = UserHandle.getUserId(uid);
+
+        Request request = null;
+        try {
+            IPackageManager ipm = AppGlobals.getPackageManager();
+            ApplicationInfo appInfo =
+                    ipm.getApplicationInfo(packageName, PackageManager.GET_META_DATA, userId);
+            if (appInfo == null) {
+                Log.w(TAG, "Null application info retrieved for package " + packageName
+                        + ", userId " + userId);
+                return null;
+            }
+
+            final UserHandle userHandle = new UserHandle(userId);
+            Drawable appIcon = mPackageManager.getApplicationIcon(appInfo);
+            Drawable icon = mPackageManager.getUserBadgedIcon(appIcon, userHandle);
+            CharSequence appLabel = mPackageManager.getApplicationLabel(appInfo);
+            CharSequence badgedAppLabel = mPackageManager.getUserBadgedLabel(appLabel, userHandle);
+            if (appLabel.toString().contentEquals(badgedAppLabel)) {
+                // If badged label is not different from original then no need for it as
+                // a separate content description.
+                badgedAppLabel = null;
+            }
+            request = new Request(packageName, userHandle, icon, appLabel, highBattery,
+                    badgedAppLabel);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error while retrieving application info for package " + packageName
+                    + ", userId " + userId, e);
+        }
+
+        return request;
+    }
+
+    public static class Request {
+        public final String packageName;
+        public final UserHandle userHandle;
+        public final Drawable icon;
+        public final CharSequence label;
+        public final boolean isHighBattery;
+        public final CharSequence contentDescription;
+
+        private Request(String packageName, UserHandle userHandle, Drawable icon,
+                CharSequence label, boolean isHighBattery, CharSequence contentDescription) {
+            this.packageName = packageName;
+            this.userHandle = userHandle;
+            this.icon = icon;
+            this.label = label;
+            this.isHighBattery = isHighBattery;
+            this.contentDescription = contentDescription;
+        }
+    }
+}
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 71aefad..ba991fb 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -8,11 +8,12 @@
                  android:process="system"
                  android:backupAgent="SettingsBackupAgent"
                  android:killAfterRestore="false"
-                 android:icon="@mipmap/ic_launcher_settings">
-                 
-    <!-- todo add: android:neverEncrypt="true" -->
+                 android:icon="@mipmap/ic_launcher_settings"
+                 android:forceDeviceEncrypted="true"
+                 android:encryptionAware="true">
 
-        <provider android:name="SettingsProvider" android:authorities="settings"
+        <provider android:name="SettingsProvider"
+                  android:authorities="settings"
                   android:multiprocess="false"
                   android:exported="true"
                   android:singleUser="true"
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 95d7772..dde9709 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -392,12 +392,9 @@
             if (DEBUG_PERSISTENCE) {
                 Slog.i(LOG_TAG, "[PERSIST END]");
             }
-
-            // Any error while writing is fatal.
         } catch (Throwable t) {
             Slog.wtf(LOG_TAG, "Failed to write settings, restoring backup", t);
             destination.failWrite(out);
-            throw new IllegalStateException("Failed to write settings, restoring backup", t);
         } finally {
             IoUtils.closeQuietly(out);
         }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 05591cc..8c39ee6 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -108,7 +108,9 @@
     <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
     <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
 
-    <application android:label="@string/app_label">
+    <application android:label="@string/app_label"
+                 android:forceDeviceEncrypted="true"
+                 android:encryptionAware="true">
         <provider
             android:name="android.support.v4.content.FileProvider"
             android:authorities="com.android.shell"
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index be5c0fe..6fda2c6 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -145,7 +145,9 @@
         android:icon="@drawable/icon"
         android:process="com.android.systemui"
         android:supportsRtl="true"
-        android:theme="@style/systemui_theme">
+        android:theme="@style/systemui_theme"
+        android:forceDeviceEncrypted="true"
+        android:encryptionAware="true">
         <!-- Keep theme in sync with SystemUIApplication.onCreate().
              Setting the theme on the application does not affect views inflated by services.
              The application theme is set again from onCreate to take effect for those views. -->
diff --git a/packages/SystemUI/res/anim/recents_fast_toggle_app_home_exit.xml b/packages/SystemUI/res/anim/recents_fast_toggle_app_home_exit.xml
new file mode 100644
index 0000000..69edcc7
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_fast_toggle_app_home_exit.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<!-- Recents Activity -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:zAdjustment="top">
+  <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
+         android:fillEnabled="true"
+         android:fillBefore="true" android:fillAfter="true"
+         android:duration="250"/>
+</set>
diff --git a/packages/SystemUI/res/drawable/docked_divider_handle.xml b/packages/SystemUI/res/drawable/docked_divider_handle.xml
new file mode 100644
index 0000000..ea32548
--- /dev/null
+++ b/packages/SystemUI/res/drawable/docked_divider_handle.xml
@@ -0,0 +1,22 @@
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle">
+    <size android:height="@dimen/docked_divider_handle_height"
+        android:width="@dimen/docked_divider_handle_width" />
+    <corners radius="1dp" />
+    <solid android:color="@color/docked_divider_handle" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/docked_stack_divider.xml b/packages/SystemUI/res/layout/docked_stack_divider.xml
new file mode 100644
index 0000000..5f42856
--- /dev/null
+++ b/packages/SystemUI/res/layout/docked_stack_divider.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<com.android.systemui.stackdivider.DividerView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent">
+
+    <View
+        style="@style/DockedDividerBackground"
+        android:id="@+id/docked_divider_background"
+        android:background="@color/docked_divider_background"/>
+
+    <ImageButton
+        style="@style/DockedDividerHandle"
+        android:id="@+id/docked_divider_handle"
+        android:layout_height="48dp"
+        android:layout_width="48dp"
+        android:background="@null"
+        android:src="@drawable/docked_divider_handle"/>
+
+</com.android.systemui.stackdivider.DividerView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 329e395..01d5e05 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Weier"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is die volumedialoog"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Raak om die oorspronklike terug te stel."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jy gebruik tans jou werkprofiel"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Stelsel-UI-ontvanger"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Wys persentasie van ingebedde battery"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index dbfc287..f677972 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -406,8 +406,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"رفض"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> هو مربع حوار مستوى الصوت"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"المس لاستعادة الإعداد الأصلي."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">"،"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"أنت تستخدم ملفك الشخصي للعمل"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"أداة ضبط واجهة مستخدم النظام"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"عرض نسبة البطارية المدمجة"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 0971753..b7f96a1 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Отказване"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> изпълнява ролята на диалоговия прозорец за силата на звука"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Докоснете, за да възстановите оригинала."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Използвате служебния си потребителски профил"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Тунер на системния потребителски интерфейс"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Показване на процента на вградената батерия"</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index afd4ac4..6a93724 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"প্রত্যাখ্যান করুন"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> হল ভলিউম ডায়লগ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"আসলটি পুনঃস্থাপন করতে স্পর্শ করুন৷"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"আপনি আপনার কাজের প্রোফাইল ব্যবহার করছেন"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"সিস্টেম UI টিউনার"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"এম্বেড করা ব্যাটারির শতকরা হার দেখায়"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 32617ed..0da503a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode d\'avió."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"No hi ha cap targeta SIM."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"S\'està canviant la xarxa de l\'operador de telefonia mòbil."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> per cent de bateria."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuració del sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacions."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Esborra la notificació."</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Denega"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> és el diàleg de volum"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca per restaurar l\'original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estàs utilitzant el perfil professional"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Personalitzador d\'interfície d\'usuari"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostra el percentatge de la bateria inserit"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 7d80a24..c9e8a83 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -404,8 +404,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odmítnout"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialog hlasitosti"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používáte pracovní profil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Nástroj na ladění uživatelského rozhraní systému"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Zobrazovat vložené procento nabití baterie"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index a40eecf..a9931ce 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Afvis"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er dialogboksen for lydstyrke"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Tryk for at gendanne originalen."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruger din arbejdsprofil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Vis procent for det indbyggede batteri"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index cd6480d..8a7fa5e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Flugmodus"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Keine SIM-Karte"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Netzwerk des Mobilfunkanbieters wird gewechselt"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Akku bei <xliff:g id="NUMBER">%d</xliff:g> Prozent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systemeinstellungen"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Benachrichtigungen"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Benachrichtigung löschen"</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Ablehnen"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> regelt die Lautstärke."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Zum Wiederherstellen des Originals hier tippen"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">"u."</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Sie verwenden Ihr Arbeitsprofil."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Eingebettete Akku-Prozentzahl anzeigen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 1fda559..47eb46f 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Λειτουργία πτήσης."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Δεν υπάρχει κάρτα SIM."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Αλλαγή δικτύου εταιρείας κινητής τηλεφωνίας."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Μπαταρία <xliff:g id="NUMBER">%d</xliff:g> τοις εκατό."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Ρυθμίσεις συστήματος."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ειδοποιήσεις."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Εκκαθάριση ειδοποίησης."</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Απόρριψη"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> αποτελεί το παράθυρο διαλόγου ελέγχου έντασης"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Αγγίξτε για επαναφορά αρχικού."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Χρησιμοποιείτε το προφίλ εργασίας σας"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Εμφάνιση ποσοστού ενσωματωμένης μπαταρίας"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 1e74e60..f257c7f 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 1e74e60..f257c7f 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 1e74e60..f257c7f 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index a11ebfa..608f73c 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Rechazar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar el original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando tu perfil de trabajo"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador de IU del sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de la batería integrada"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 3a24cd1..5ac93c6 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Ukatu"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> da bolumenaren leihoa"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Ukitu jatorrizkora leheneratzeko"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Work profila erabiltzen ari zara"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sistemako erabiltzaile-interfazearen konfiguratzailea"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Erakutsi txertatutako bateriaren ehunekoa"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index f62ca02..837b727 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"اجازه ندارد"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> کنترل‌کننده صدا است"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"برای بازیابی کنترل‌کننده اصلی، لمس کنید."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">"،"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"درحال استفاده از نمایه کاری‌تان هستید"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"تنظیم‌کننده واسط کاربری سیستم"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"نمایش درصد شارژ باتری جاسازی شده"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index f1974ca..ef6a064 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Estä"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on äänenvoimakkuusvalinta."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Palauta alkuperäinen koskettamalla."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Käytät työprofiilia."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Näytä akun varaus kuvakkeessa"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index a100cbf..52d2e2a 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Aucune carte SIM."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Modification du réseau du fournisseur de services"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Pile : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Refuser"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touchez pour restaurer l\'original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de charge"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 8f6205a..39a8dbc 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Aucune carte SIM"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Modification du réseau de l\'opérateur"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterie : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Refuser"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Appuyez pour restaurer l\'interface d\'origine."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de la batterie"</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 8d3a9f8..398a055 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Non hai tarxeta SIM"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Cambio de rede do operador."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Carga da batería: <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuración do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacións"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Eliminar notificación."</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Denegar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é o cadro de diálogo de volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar o orixinal."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando o perfil de traballo"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Configurador da IU do sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaxe de batería inserida"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index c4a10cc..dafc96f 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -403,8 +403,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odbij"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> predstavlja dijaloški okvir za upravljanje glasnoćom"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da biste vratili izvorno."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Upotrebljavate radni profil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Ugađanje korisničkog sučelja sustava"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži ugrađeni postotak baterije"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index f8c88c9..cf08b55 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Elutasítás"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás kezeli a hangerőt"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Érintse meg az eredeti érték visszaállításához."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"A munkaprofilt használja"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Kezelőfelület-hangoló"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"A beépített akkumulátor töltöttségi szintjének megjelenítése"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 784008d..b4a265d 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Մերժել"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը ձայնի ուժգնության երկխոսության հավելված է"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Դիպչեք՝ սկզբնօրինակը վերականգնելու համար:"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Դուք օգտագործում եք ձեր աշխատանքային պրոֆիլը"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Համակարգի ՕՄ-ի կարգավորիչ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Ցուցադրել ներկառուցված մարտկոցի տոկոսայնությունը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index fd30834..6d6c1c7 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Tolak"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah dialog volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan aslinya."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda menggunakan profil kerja"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Penyetel Antarmuka Pengguna Sistem"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Tampilkan persentase baterai yang tersemat"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 32baffd..8e7711e4 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Hafna"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er hljóðstyrksvalmyndin"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Snertu til að færa í upprunalegt horf."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Þú ert að nota vinnusniðið"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Fínstillingar kerfisviðmóts"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Sýna innfellda rafhlöðustöðu"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 28bba7b..f12e626 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modalità aereo."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Nessuna SIM presente."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Cambio rete operatore."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteria: <xliff:g id="NUMBER">%d</xliff:g> percento."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Impostazioni di sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifiche."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Cancella notifica."</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Nega"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> rappresenta la finestra di dialogo relativa al volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Tocca per ripristinare l\'originale."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Stai utilizzando il profilo di lavoro"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintetizzatore interfaccia utente di sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostra percentuale batteria incorporata"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 7581ace..c168f7d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -404,8 +404,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"דחה"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא תיבת הדו-שיח של עוצמת הקול"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"גע כדי לשחזר את עוצמת הקול המקורית."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"אתה משתמש בפרופיל העבודה שלך"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"הצג בשורת הסטטוס את אחוז עוצמת הסוללה"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 8d86ee3..f053ee4 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"許可しない"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>を音量ダイアログとして使用"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"タップすると元の音量ダイアログが復元されます。"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">"、"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"仕事用プロファイルを使用しています"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"システムUI調整ツール"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"内蔵電池の残量の割合を表示する"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 92bd57a..8d754c4 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"უარყოფა"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ხმოვან დიალოგშია"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ორიგინალის აღდგენისათვის, შეეხეთ."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"თქვენ სამსახურის პროფილს იყენებთ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"სისტემის UI ტუნერი"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ჩამაგრებული ბატარეის პროცენტის ჩვენება"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 5a0ed5f..d0bd8bb 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Өшіру"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> — көлем диалогтық терезесі"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнұсқаны қалпына келтіру үшін түртіңіз."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Сіз жұмыс профиліңізді пайдаланып жатырсыз"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Жүйелік пайдаланушылық интерфейс тюнері"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Ендірілген батарея пайыздық шамасын көрсету"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 0735cb1..d77f480 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"បដិសេធ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាប្រអប់សម្លេង"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ប៉ះដើម្បីស្តារច្បាប់ដើម។"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"អ្នកកំពុងប្រើប្រវត្តិរូបការងាររបស់អ្នក"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"កម្មវិធីសម្រួល UI ប្រព័ន្ធ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"បង្ហាញភាគរយថាមពលថ្មដែលបានបង្កប់"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 0554f21..3b9dfc2 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ನಿರಾಕರಿಸು"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ವಾಲ್ಯೂಮ್ ಸಂವಾದವಾಗಿದೆ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ಮೂಲ ಮರುಸ್ಥಾಪಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ನಿಮ್ಮ ಕೆಲಸದ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು ನೀವು ಬಳಸುತ್ತಿರುವಿರಿ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ಎಂಬೆಡ್ ಮಾಡಲಾದ ಬ್ಯಾಟರಿ ಶೇಕಡಾ ತೋರಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index c7c9f15..a5f14e4 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"거부"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>은(는) 볼륨 대화입니다."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"원본을 복원하려면 터치하세요."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"직장 프로필을 사용하고 있습니다."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"시스템 UI 튜너"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"내장형 배터리 잔량 비율 표시"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index fe5d75d..2d6dc6f 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Жок"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> үндү катуулатуу диалогу"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнусканы калыбына келтирүү үчүн тийип коюңуз."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Жумуш профилиңизди колдонуп жатасыз"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Батарянын кубатнын деңгээли пайыз менен көрсөтлсүн"</string>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 6ef1ada..456391d 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -22,4 +22,7 @@
     <!-- Standard notification width + gravity -->
     <dimen name="notification_panel_width">@dimen/standard_notification_panel_width</dimen>
     <integer name="notification_panel_layout_gravity">@integer/standard_notification_panel_layout_gravity</integer>
+
+    <dimen name="docked_divider_handle_width">2dp</dimen>
+    <dimen name="docked_divider_handle_height">24dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index 8919198..dd396d9 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -18,4 +18,15 @@
     <style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer">
         <item name="android:layout_width">360dp</item>
     </style>
+
+    <style name="DockedDividerBackground">
+        <item name="android:layout_width">12dp</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_gravity">center_horizontal</item>
+    </style>
+
+    <style name="DockedDividerHandle">
+        <item name="android:layout_gravity">center_vertical</item>
+    </style>
+
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index ca3470c..82a82e6 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ປະຕິເສດ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນ​ໜ້າ​ຕ່າງ​ລະ​ດັບ​ສຽງ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ສໍາ​ຜັດ​ເພື່ອກູ້​ຄືນ​ຕົ້ນ​ສະ​ບັບ​."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ທ່ານກຳລັງໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ສະ​ແດງ​ເປີ​ເຊັນ​ແບັດ​ເຕີ​ຣີ​ທີ່​ຕິດ​ມາ"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index f6eb099..27663bd 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -403,8 +403,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Neatļaut"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ir skaļuma dialoglodziņš"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Pieskarieties, lai atjaunotu sākotnējo."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jūs izmantojat darba profilu."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sistēmas saskarnes regulators"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Rādīt akumulatora uzlādes līmeni procentos"</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index dbd3aed..7162a5c 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим на работа во авион."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Нема СИМ-картичка"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Променување на мрежата на операторот."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија <xliff:g id="NUMBER">%d</xliff:g> проценти."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Подесувања на систем."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Известувања"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Избриши известување."</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index ace8ca4..5df98ec 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"നിരസിക്കുക"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>, വോളിയം ഡയലോഗാണ്"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ആദ്യത്തേത് പുനഃസ്ഥാപിക്കാൻ സ്‌പർശിക്കുക."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"നിങ്ങൾ ഉപയോഗിക്കുന്നത് ഔദ്യോഗിക പ്രൊഫൈലാണ്"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"സിസ്റ്റം UI ട്യൂണർ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"എംബഡ് ചെയ്‌ത ബാറ്ററി ശതമാനം കാണിക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 698ed8a..f960dfa 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -400,8 +400,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Татгалзах"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь дууны диалог юм."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Анхны хувилбарыг эргүүлэн хадгалахыг хүсвэл хүрнэ үү."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Та өөрийн ажлын профайлыг ашиглаж байна"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Системийн UI Тохируулагч"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Залгаатай тэжээлийн хувийг харуулах"</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 1168a71..f599aca 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"नकार द्या"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा व्हॉल्यूम संवाद आहे"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"मूळ पुनर्संचयित करण्यासाठी स्पर्श करा."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आपण आपले कार्य प्रोफाईल वापरत आहात"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टीम UI ट्यूनर"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेडेड बॅटरी टक्केवारी दर्शवा"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 7b6e60c..7cfcbe2 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -384,7 +384,7 @@
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheten forblir låst til du låser den opp manuelt"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Motta varsler raskere"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Se dem før du låser opp"</string>
-    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei takk"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei, takk"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Konfigurer"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="3179845345429841822">"Avslutt nå"</string>
@@ -393,7 +393,7 @@
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skjermen er låst"</string>
     <string name="screen_pinning_description" msgid="3577937698406151604">"På denne måten blir skjermen synlig frem til du låser den opp. Trykk og hold inne Tilbake for å låse opp."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Skjønner"</string>
-    <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei takk"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei, takk"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vil du skjule <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Den vises igjen neste gang du slår den på i innstillingene."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skjul"</string>
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Ikke tillat"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er volumdialogen"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Trykk for å gå tilbake til den opprinnelige volumdialogen."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruker jobbprofilen din"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Vis prosent for det innebygde batteriet"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index c854a55..078f783 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"अस्वीकार गर्नुहोस्"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> भोल्यूम संवाद हो"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"मूल पुनर्स्थापना गर्न छुनुहोस्।"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"तपाईँले कार्य प्रोफाइल प्रयोग गर्दै हुनुहुन्छ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"प्रणाली UI ट्युनर"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"इम्बेड गरिएको ब्याट्री प्रतिशत देखाउनुहोस्"</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index b67b75a..e5cbf1f 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੋਲਯੂਮ ਡਾਇਲੌਗ ਹੈ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ਅਸਲੀ ਨੂੰ ਰੀਸਟੋਰ ਕਰਨ ਲਈ ਛੋਹਵੋ।"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ਤੁਸੀਂ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਵਰਤ ਰਹੇ ਹੋ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI ਟਿਊਨਰ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ਜੋਡ਼ੀ ਗਈ ਬੈਟਰੀ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 48c4259..65d19bb 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -404,8 +404,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odmów"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> steruje głośnością"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Dotknij, by przywrócić pierwotną."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Używasz profilu do pracy"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Kalibrator System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Pokaż procent naładowania baterii"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index c7044a3..8448717 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Negar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 96dccf6..6abe9a9 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Recusar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo do volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Está a utilizar o seu perfil de trabalho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador da interface do sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar percentagem da bateria incorporada"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index c7044a3..8448717 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Negar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 3d38d62..b45347f 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -151,7 +151,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mod Avion."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Niciun card SIM."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Se schimbă rețeaua operatorului."</string>
-    <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> procente."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> la sută."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Setări de sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificări."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ștergeți notificarea."</string>
@@ -403,8 +403,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Refuzați"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> afișează caseta de dialog pentru volum"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Atingeți pentru a reveni la setarea inițială."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Acum folosiți profilul de serviciu"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Afișați procentajul bateriei încorporat"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index c3fd224..96971ea 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -152,9 +152,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полета."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Нет SIM-карты."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Сменить сеть"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд батареи в процентах: <xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Настройки"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Уведомления"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Удалить уведомление"</string>
@@ -406,8 +404,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Нет"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> назначено регулятором громкости"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Нажмите, чтобы восстановить приложение по умолчанию."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Вы перешли в рабочий профиль"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Показывать уровень заряда батареи в процентах"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 3ac91d1..64d460e 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ප්‍රතික්ෂේප කරන්න"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාරිතා සංවාදයයි"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"මුල් තත්ත්වය නැවත ප්‍රතිසාධනය කිරීමට ස්පර්ශ කරන්න."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ඔබ ඔබේ කාර්යාල පැතිකඩ භාවිත කරමින් සිටී"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"පද්ධති UI සුසරකය"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"කාවද්දන ලද බැටරි ප්‍රතිශතය පෙන්වන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index f3f935e..def49e9 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -152,9 +152,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim v lietadle."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Žiadna SIM karta."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Zmena siete operátora"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Batéria <xliff:g id="NUMBER">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Nastavenia systému."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Upozornenia."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Vymazať upozornenie."</string>
@@ -406,8 +404,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odmietnuť"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialóg hlasitosti"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používate svoj pracovný profil."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Tuner používateľského rozhrania systému"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Zobraziť percentá vloženej batérie"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c53bddd..14d3bdb 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -404,8 +404,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Zavrni"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je pogovorno okno glede prostornine"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Dotaknite se, če želite obnoviti izvirnik."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Uporabljate delovni profil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Uglaševalnik uporabniškega vmesnika sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži odstotek napolnjenosti vgraj. akumulatorja"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 842d788..2139441 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -403,8 +403,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Одбиј"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> је дијалог за јачину звука"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Додирните да бисте вратили оригинал."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Користите профил за Work"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Тјунер за кориснички интерфејс система"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Приказуј уграђени проценат батерије"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index ee734ff..ad7bffd 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Neka"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> används som volymkontroll"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Tryck här om du vill återställa den ursprungliga appen."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du använder din jobbprofil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Inställningar för systemgränssnitt"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Visa inbäddad batteriprocent"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 4a10f67..244e58d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Kataa"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ni mazungumzo ya sauti"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Gusa ili urejeshe ya awali."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Unatumia wasifu wako wa kazini"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Kipokea Ishara cha SystemUI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Onyesha asilimia ya betri iliyopachikwa"</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 6474bb7..9bd280d 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"நிராகரி"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"ஒலியளவு செய்தி: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"அசலை மீட்டமைக்கத் தொடவும்."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"பணி சுயவிவரத்தைப் பயன்படுத்துகிறீர்கள்"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"உள்ளிணைந்த பேட்டரி சதவீதத்தைக் காட்டு"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 54987a2..256b497 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ปฏิเสธ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นช่องโต้ตอบระดับเสียง"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"แตะเพื่อคืนค่าดั้งเดิม"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"คุณกำลังใช้โปรไฟล์งานของคุณ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"ตัวรับสัญญาณ UI ระบบ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"แสดงเปอร์เซ็นต์ของแบตเตอรี่ในตัว"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index d8778a0..66b0b6b 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Tanggihan"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ang volume dialog"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Pindutin upang ibalik ang orihinal."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ginagamit mo ang iyong profile sa trabaho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Tuner ng System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Ipakita ang naka-embed na porsyento ng baterya"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 066ffbb..5a6e5db 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Reddet"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ses denetimi iletişim kutusu olarak ayarlandı"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinali geri yüklemek için dokunun."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi kullanıyorsunuz"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sistem Arayüzü Ayarlayıcısı"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Yerleşik pil yüzdesini göster"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 9abfebf..75160cd9 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"مسترد کریں"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> والیوم ڈائلاگ ہے"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"اصل کو بحال کرنے کیلئے ٹچ کریں۔"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">"،"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"آپ اپنا دفتری پروفائل استعمال کر رہے ہیں۔"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"‏سسٹم UI ٹیونر"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"سرایت کردہ بیٹری کی فیصد دکھائیں"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 79a18a2..5ddd115 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -145,10 +145,10 @@
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Rouming"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
-    <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-karta yo‘q."</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM karta yo‘q."</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth modem"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Parvoz rejimi"</string>
-    <string name="accessibility_no_sims" msgid="3957997018324995781">"Hech qanday SIM-karta yo‘q."</string>
+    <string name="accessibility_no_sims" msgid="3957997018324995781">"Hech qanday SIM karta yo‘q."</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Mobil tarmoqni o‘zgartirish"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Tizim sozlamalari."</string>
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Rad etish"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ovoz balandligini boshqaradi"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Aslini tiklash uchun bosing."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Siz ishchi profildan foydalanmoqdasiz"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"SystemUI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Batareya foizi ko‘rsatilsin"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index a195382..1a5cc8b 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Từ chối"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> là hộp thoại khối lượng"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Chạm để khôi phục bản gốc."</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Bạn đang sử dụng hồ sơ công việc của mình"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Bộ điều hướng giao diện người dùng hệ thống"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Hiển thị tỷ lệ phần trăm pin được nhúng"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cca4f6f..0c6b2c9 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -150,9 +150,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"飞行模式。"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"没有 SIM 卡。"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"运营商网络正在更改。"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"电池电量为百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"系统设置。"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
@@ -404,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"拒绝"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已用作音量控制对话框"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"触摸即可恢复原始设置。"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">"、"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您当前正在使用工作资料"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"系统界面调谐器"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"嵌入式显示电池电量百分比 显示嵌入的电池电量百分比"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index b529e39..8d238d5 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -402,8 +402,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"拒絕"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在是預設的音量控制對話方塊。"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸這裡即可恢復原始設定。"</string>
-    <!-- no translation found for group_summary_concadenation (2705151242008937028) -->
-    <skip />
+    <string name="group_summary_concadenation" msgid="2705151242008937028">"、"</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用 Work 設定檔"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"系統使用者介面調整精靈"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"顯示嵌入式電池百分比"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f40f0d9..26a0577 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -143,4 +143,7 @@
 
     <color name="fab_ripple">#1fffffff</color><!-- 12% white -->
     <color name="fab_shape">#ff009688</color><!-- Teal 500 -->
+
+    <color name="docked_divider_background">#ff000000</color>
+    <color name="docked_divider_handle">#ffffff</color>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c413524..73f63a9 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -577,4 +577,11 @@
 
     <!-- TODO: Remove this -->
     <dimen name="qs_header_neg_padding">-8dp</dimen>
+
+    <!-- How high we lift the divider when touching -->
+    <dimen name="docked_stack_divider_lift_elevation">6dp</dimen>
+
+    <dimen name="docked_divider_handle_width">24dp</dimen>
+    <dimen name="docked_divider_handle_height">2dp</dimen>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 9e942f0..4462a03 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -304,4 +304,14 @@
         <item name="android:background">@drawable/btn_borderless_rect</item>
     </style>
 
+    <style name="DockedDividerBackground">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">12dp</item>
+        <item name="android:layout_gravity">center_vertical</item>
+    </style>
+
+    <style name="DockedDividerHandle">
+        <item name="android:layout_gravity">center_horizontal</item>
+    </style>
+
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 9551fb7..949efc5 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -27,6 +27,8 @@
 import android.os.UserHandle;
 import android.util.Log;
 
+import com.android.systemui.stackdivider.Divider;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -51,6 +53,7 @@
             com.android.systemui.power.PowerUI.class,
             com.android.systemui.media.RingtonePlayer.class,
             com.android.systemui.keyboard.KeyboardUI.class,
+            Divider.class
     };
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 2ea1e43..eee685f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -379,6 +379,13 @@
         @Override
         public void onDeviceProvisioned() {
             sendUserPresentBroadcast();
+            synchronized (KeyguardViewMediator.this) {
+                // If system user is provisioned, we might want to lock now to avoid showing launcher
+                if (UserManager.isSplitSystemUser()
+                        && KeyguardUpdateMonitor.getCurrentUser() == UserHandle.USER_SYSTEM) {
+                    doKeyguardLocked(null);
+                }
+            }
         }
 
         @Override
@@ -1054,7 +1061,8 @@
 
         // In split system user mode, we never unlock system user.
         if (!UserManager.isSplitSystemUser()
-                || KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM) {
+                || KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM
+                || !mUpdateMonitor.isDeviceProvisioned()) {
 
             // if the setup wizard hasn't run yet, don't show
             final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index ebfacac..a429447 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -21,6 +21,7 @@
  */
 public class Constants {
 
+    // TODO: Move into RecentsMetrics
     public static class Metrics {
         // DO NOT MODIFY THE ORDER OF THESE METRICS
         public static final int DismissSourceKeyboard = 0;
@@ -28,6 +29,7 @@
         public static final int DismissSourceHeaderButton = 2;
     }
 
+    // TODO: Move into RecentsDebugFlags
     public static class DebugFlags {
 
         public static class App {
@@ -37,7 +39,7 @@
             public static final boolean EnableTaskFiltering = false;
             // Enables dismiss-all
             public static final boolean EnableDismissAll = false;
-            // Enables fast-toggling
+            // Enables fast-toggling by just tapping on the recents button
             public static final boolean EnableFastToggleRecents = false;
             // Enables the thumbnail alpha on the front-most task
             public static final boolean EnableThumbnailAlphaOnFrontmost = false;
@@ -57,14 +59,4 @@
             public static final int SystemServicesProxyMockTaskCount = 100;
         }
     }
-
-    public static class Values {
-        public static class App {
-            public static int AppWidgetHostId = 1024;
-        }
-
-        public static class TaskStackView {
-            public static final int FilterStartDelay = 25;
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index a58bc58..95f1eb2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -27,6 +27,7 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Log;
 import android.view.Display;
 import android.view.View;
@@ -193,6 +194,12 @@
      */
     @Override
     public void showRecents(boolean triggeredFromAltTab, View statusBarView) {
+        // Ensure the device has been provisioned before allowing the user to interact with
+        // recents
+        if (!isDeviceProvisioned()) {
+            return;
+        }
+
         if (proxyToOverridePackage(ACTION_SHOW_RECENTS)) {
             return;
         }
@@ -222,6 +229,12 @@
      */
     @Override
     public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+        // Ensure the device has been provisioned before allowing the user to interact with
+        // recents
+        if (!isDeviceProvisioned()) {
+            return;
+        }
+
         if (proxyToOverridePackage(ACTION_HIDE_RECENTS)) {
             return;
         }
@@ -251,6 +264,12 @@
      */
     @Override
     public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
+        // Ensure the device has been provisioned before allowing the user to interact with
+        // recents
+        if (!isDeviceProvisioned()) {
+            return;
+        }
+
         if (proxyToOverridePackage(ACTION_TOGGLE_RECENTS)) {
             return;
         }
@@ -280,6 +299,12 @@
      */
     @Override
     public void preloadRecents() {
+        // Ensure the device has been provisioned before allowing the user to interact with
+        // recents
+        if (!isDeviceProvisioned()) {
+            return;
+        }
+
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.preloadRecents();
@@ -302,6 +327,12 @@
 
     @Override
     public void cancelPreloadingRecents() {
+        // Ensure the device has been provisioned before allowing the user to interact with
+        // recents
+        if (!isDeviceProvisioned()) {
+            return;
+        }
+
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.cancelPreloadingRecents();
@@ -329,11 +360,23 @@
 
     @Override
     public void showNextAffiliatedTask() {
+        // Ensure the device has been provisioned before allowing the user to interact with
+        // recents
+        if (!isDeviceProvisioned()) {
+            return;
+        }
+
         mImpl.showNextAffiliatedTask();
     }
 
     @Override
     public void showPrevAffiliatedTask() {
+        // Ensure the device has been provisioned before allowing the user to interact with
+        // recents
+        if (!isDeviceProvisioned()) {
+            return;
+        }
+
         mImpl.showPrevAffiliatedTask();
     }
 
@@ -386,8 +429,8 @@
      * Handle screen pinning request.
      */
     public final void onBusEvent(final ScreenPinningRequestEvent event) {
-        int processUser = event.systemServicesProxy.getProcessUser();
-        if (event.systemServicesProxy.isSystemUser(processUser)) {
+        int processUser = sSystemServicesProxy.getProcessUser();
+        if (sSystemServicesProxy.isSystemUser(processUser)) {
             mImpl.onStartScreenPinning(event.applicationContext);
         } else {
             postToSystemUser(new Runnable() {
@@ -456,6 +499,14 @@
     }
 
     /**
+     * @return whether this device is provisioned.
+     */
+    private boolean isDeviceProvisioned() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+    }
+
+    /**
      * Attempts to proxy the following action to the override recents package.
      * @return whether the proxying was successful
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index ab05bb0..3ae8827 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -32,19 +32,22 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewStub;
 import android.view.ViewTreeObserver;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.AppWidgetProviderChangedEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationStartedEvent;
+import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
+import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
+import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -57,7 +60,6 @@
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
-import com.android.systemui.recents.misc.Console;
 import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -104,44 +106,44 @@
     // Runnables to finish the Recents activity
     FinishRecentsRunnable mFinishLaunchHomeRunnable;
 
-    // Runnable to be executed after we paused ourselves
-    Runnable mAfterPauseRunnable;
-
     // The trigger to automatically launch the current task
     DozeTrigger mIterateTrigger = new DozeTrigger(500, new Runnable() {
         @Override
         public void run() {
-            boolean dismissed = dismissRecentsToFocusedTask(false);
+            dismissRecentsToFocusedTask(false);
         }
     });
 
     /**
-     * A common Runnable to finish Recents either by calling finish() (with a custom animation) or
-     * launching Home with some ActivityOptions.  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.  The only case where we finish() directly is when we are cancelling the full
-     * screen transition from the app.
+     * 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
+     * just finishing the activity since we don't know what is behind Recents in the task stack.
      */
     class FinishRecentsRunnable implements Runnable {
         Intent mLaunchIntent;
-        ActivityOptions mLaunchOpts;
 
         /**
-         * Creates a finish runnable that starts the specified intent, using the given
-         * ActivityOptions.
+         * Creates a finish runnable that starts the specified intent.
          */
-        public FinishRecentsRunnable(Intent launchIntent, ActivityOptions opts) {
+        public FinishRecentsRunnable(Intent launchIntent) {
             mLaunchIntent = launchIntent;
-            mLaunchOpts = opts;
         }
 
         @Override
         public void run() {
             try {
-                startActivityAsUser(mLaunchIntent, mLaunchOpts.toBundle(), UserHandle.CURRENT);
+                RecentsActivityLaunchState launchState =
+                        Recents.getConfiguration().getLaunchState();
+                ActivityOptions opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this,
+                        launchState.launchedFromSearchHome ?
+                                R.anim.recents_to_search_launcher_enter :
+                                R.anim.recents_to_launcher_enter,
+                        launchState.launchedFromSearchHome ?
+                                R.anim.recents_to_search_launcher_exit :
+                                R.anim.recents_to_launcher_exit);
+                startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
             } catch (Exception e) {
-                Console.logError(RecentsActivity.this,
-                        getString(R.string.recents_launch_error_message, "Home"));
+                Log.e(TAG, getString(R.string.recents_launch_error_message, "Home"), e);
             }
         }
     }
@@ -193,18 +195,6 @@
             mRecentsView.setTaskStack(stack);
         }
 
-        // Create the home intent runnable
-        Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
-        homeIntent.addCategory(Intent.CATEGORY_HOME);
-        homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-        mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent,
-            ActivityOptions.makeCustomAnimation(this,
-                    launchState.launchedFromSearchHome ? R.anim.recents_to_search_launcher_enter :
-                        R.anim.recents_to_launcher_enter,
-                    launchState.launchedFromSearchHome ? R.anim.recents_to_search_launcher_exit :
-                        R.anim.recents_to_launcher_exit));
-
         // Mark the task that is the launch target
         int launchTaskIndexInStack = 0;
         if (launchState.launchedToTaskId != -1) {
@@ -348,7 +338,7 @@
 
         // Initialize the widget host (the host id is static and does not change)
         if (!Constants.DebugFlags.App.DisableSearchBar) {
-            mAppWidgetHost = new RecentsAppWidgetHost(this, Constants.Values.App.AppWidgetHostId);
+            mAppWidgetHost = new RecentsAppWidgetHost(this, RecentsAppWidgetHost.HOST_ID);
         }
         mPackageMonitor = new RecentsPackageMonitor();
         mPackageMonitor.register(this);
@@ -363,6 +353,13 @@
         mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
         mScrimViews = new SystemBarScrimViews(this);
 
+        // Create the home intent runnable
+        Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
+        homeIntent.addCategory(Intent.CATEGORY_HOME);
+        homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+        mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent);
+
         // Bind the search app widget when we first start up
         if (!Constants.DebugFlags.App.DisableSearchBar) {
             mSearchWidgetInfo = ssp.getOrBindSearchAppWidget(this, mAppWidgetHost);
@@ -398,7 +395,7 @@
         boolean wasLaunchedByAm = !launchState.launchedFromHome &&
                 !launchState.launchedFromAppWithThumbnail;
         if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
-            EventBus.getDefault().send(new EnterRecentsWindowAnimationStartedEvent());
+            EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
         }
 
         if (!launchState.launchedHasConfigurationChanged) {
@@ -424,11 +421,18 @@
     }
 
     @Override
+    public void onEnterAnimationComplete() {
+        super.onEnterAnimationComplete();
+        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+    }
+
+    @Override
     protected void onPause() {
         super.onPause();
-        if (mAfterPauseRunnable != null) {
-            mRecentsView.post(mAfterPauseRunnable);
-            mAfterPauseRunnable = null;
+
+        if (Constants.DebugFlags.App.EnableFastToggleRecents) {
+            // Stop the fast-toggle dozer
+            mIterateTrigger.stopDozing();
         }
 
         if (Constants.DebugFlags.App.EnableFastToggleRecents) {
@@ -513,12 +517,7 @@
                 if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) {
                     // As we iterate to the next/previous task, cancel any current/lagging window
                     // transition animations
-                    RecentsConfiguration config = Recents.getConfiguration();
-                    RecentsActivityLaunchState launchState = config.getLaunchState();
-                    if (launchState.launchedToTaskId != -1) {
-                        SystemServicesProxy ssp = Recents.getSystemServices();
-                        ssp.cancelWindowTransition(launchState.launchedToTaskId);
-                    }
+                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
 
                     // Focus the next task in the stack
                     final boolean backward = event.isShiftPressed();
@@ -577,25 +576,10 @@
     /**** RecentsView.RecentsViewCallbacks Implementation ****/
 
     @Override
-    public void onTaskViewClicked() {
-    }
-
-    @Override
-    public void onTaskLaunchFailed() {
-        // Return to Home
-        dismissRecentsToHome(true);
-    }
-
-    @Override
     public void onAllTaskViewsDismissed() {
         mFinishLaunchHomeRunnable.run();
     }
 
-    @Override
-    public void runAfterPause(Runnable r) {
-        mAfterPauseRunnable = r;
-    }
-
     /**** EventBus events ****/
 
     public final void onBusEvent(ToggleRecentsEvent event) {
@@ -624,7 +608,7 @@
         }
     }
 
-    public final void onBusEvent(EnterRecentsWindowAnimationStartedEvent event) {
+    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
         // Try and start the enter animation (or restart it on configuration changed)
         ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
         ViewAnimation.TaskViewEnterContext ctx = new ViewAnimation.TaskViewEnterContext(t);
@@ -664,6 +648,17 @@
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
     }
 
+    public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
+        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
+        int launchToTaskId = launchState.launchedToTaskId;
+        if (launchToTaskId != -1 &&
+                (event.launchTask == null || launchToTaskId != event.launchTask.key.id)) {
+            SystemServicesProxy ssp = Recents.getSystemServices();
+            ssp.cancelWindowTransition(launchState.launchedToTaskId);
+            ssp.cancelThumbnailTransition(getTaskId());
+        }
+    }
+
     public final void onBusEvent(AppWidgetProviderChangedEvent event) {
         refreshSearchWidgetView();
     }
@@ -707,6 +702,17 @@
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_BEHIND);
     }
 
+    public final void onBusEvent(LaunchTaskSucceededEvent event) {
+        MetricsLogger.histogram(this, "overview_task_launch_index", event.taskIndexFromStackFront);
+    }
+
+    public final void onBusEvent(LaunchTaskFailedEvent event) {
+        // Return to Home
+        dismissRecentsToHome(true);
+
+        MetricsLogger.count(this, "overview_task_launch_failed", 1);
+    }
+
     public final void onBusEvent(ScreenPinningRequestEvent event) {
         MetricsLogger.count(this, "overview_screen_pinned", 1);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index 9ee6f5b..01ffd2a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -19,7 +19,6 @@
 /**
  * The launch state of the RecentsActivity.
  *
- * TODO: We will be refactoring this out RecentsConfiguration.
  * Current Constraints:
  *  - needed in onStart() before onNewIntent()
  *  - needs to be reset when Recents is hidden
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
index fc96c11..573db98 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
@@ -26,6 +26,8 @@
 /** Our special app widget host for the Search widget */
 public class RecentsAppWidgetHost extends AppWidgetHost {
 
+    public static final int HOST_ID = 1024;
+
     boolean mIsListening;
 
     public RecentsAppWidgetHost(Context context, int hostId) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 675ef2f..50aa2f7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.recents;
 
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ITaskStackListener;
@@ -32,24 +30,23 @@
 import android.os.Handler;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.Log;
 import android.util.MutableBoolean;
 import android.view.AppTransitionAnimationSpec;
 import android.view.LayoutInflater;
 import android.view.View;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationStartedEvent;
+import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
-import com.android.systemui.recents.misc.Console;
+import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.ForegroundThread;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsTaskLoadPlan;
@@ -57,25 +54,32 @@
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskGrouping;
 import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.recents.views.TaskStackView;
 import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
+import com.android.systemui.recents.views.TaskStackView;
 import com.android.systemui.recents.views.TaskViewHeader;
 import com.android.systemui.recents.views.TaskViewTransform;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 import java.util.ArrayList;
 
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+
 /**
  * An implementation of the Recents component for the current user.  For secondary users, this can
  * be called remotely from the system user.
  */
 public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub
-        implements ActivityOptions.OnAnimationStartedListener, ActivityOptions.OnAnimationFinishedListener {
+        implements ActivityOptions.OnAnimationFinishedListener {
 
     private final static String TAG = "RecentsImpl";
     private final static boolean DEBUG = false;
 
-    private final static int sMinToggleDelay = 350;
+    // The minimum amount of time between each recents button press that we will handle
+    private final static int MIN_TOGGLE_DELAY_MS = 350;
+    // The duration within which the user releasing the alt tab (from when they pressed alt tab)
+    // that the fast alt-tab animation will run.  If the user's alt-tab takes longer than this
+    // duration, then we will toggle recents after this duration.
+    private final static int FAST_ALT_TAB_DELAY_MS = 225;
 
     public final static String RECENTS_PACKAGE = "com.android.systemui";
     public final static String RECENTS_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
@@ -135,7 +139,6 @@
     TaskStackListenerImpl mTaskStackListener;
     RecentsAppWidgetHost mAppWidgetHost;
     boolean mBootCompleted;
-    boolean mStartAnimationTriggered;
     boolean mCanReuseTaskStackViews = true;
 
     // Task launching
@@ -156,6 +159,14 @@
     // Variables to keep track of if we need to start recents after binding
     boolean mTriggeredFromAltTab;
     long mLastToggleTime;
+    DozeTrigger mFastAltTabTrigger = new DozeTrigger(FAST_ALT_TAB_DELAY_MS, new Runnable() {
+        @Override
+        public void run() {
+            // When this fires, then the user has not released alt-tab for at least
+            // FAST_ALT_TAB_DELAY_MS milliseconds
+            showRecents(mTriggeredFromAltTab);
+        }
+    });
 
     Bitmap mThumbnailTransitionBitmapCache;
     Task mThumbnailTransitionBitmapCacheKey;
@@ -164,7 +175,7 @@
     public RecentsImpl(Context context) {
         mContext = context;
         mHandler = new Handler();
-        mAppWidgetHost = new RecentsAppWidgetHost(mContext, Constants.Values.App.AppWidgetHostId);
+        mAppWidgetHost = new RecentsAppWidgetHost(mContext, RecentsAppWidgetHost.HOST_ID);
         Resources res = mContext.getResources();
         LayoutInflater inflater = LayoutInflater.from(mContext);
 
@@ -239,6 +250,29 @@
     @Override
     public void showRecents(boolean triggeredFromAltTab) {
         mTriggeredFromAltTab = triggeredFromAltTab;
+        if (mFastAltTabTrigger.hasTriggered()) {
+            // We are calling this from the doze trigger, so just fall through to show Recents
+            mFastAltTabTrigger.resetTrigger();
+        } else if (mFastAltTabTrigger.isDozing()) {
+            // We are dozing but haven't yet triggered, ignore this if this is not another alt-tab,
+            // otherwise, this is an additional tab (alt-tab*), which means that we should trigger
+            // immediately (fall through and disable the pending trigger)
+            // TODO: This is tricky, we need to handle the tab key, but Recents has not yet started
+            //       so we may actually additional signal to handle multiple quick tab cases.  The
+            //       severity of this is inversely proportional to the FAST_ALT_TAB_DELAY_MS
+            //       duration though
+            if (!triggeredFromAltTab) {
+                return;
+            }
+            mFastAltTabTrigger.stopDozing();
+        } else {
+            // Otherwise, the doze trigger is not running, and if this is an alt tab, we should
+            // start the trigger and then wait for the hide (or for it to elapse)
+            if (triggeredFromAltTab) {
+                mFastAltTabTrigger.startDozing();
+                return;
+            }
+        }
 
         try {
             // Check if the top task is in the home stack, and start the recents activity
@@ -249,13 +283,24 @@
                 startRecentsActivity(topTask, isTopTaskHome.value);
             }
         } catch (ActivityNotFoundException e) {
-            Console.logRawError("Failed to launch RecentAppsIntent", e);
+            Log.e(TAG, "Failed to launch RecentsActivity", e);
         }
     }
 
     @Override
     public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         if (mBootCompleted) {
+            if (triggeredFromAltTab && mFastAltTabTrigger.isDozing()) {
+                // The user has released alt-tab before the trigger has run, so just show the next
+                // task immediately
+                showNextTask();
+
+                // Cancel the fast alt-tab trigger
+                mFastAltTabTrigger.stopDozing();
+                mFastAltTabTrigger.resetTrigger();
+                return;
+            }
+
             // Defer to the activity to handle hiding recents, if it handles it, then it must still
             // be visible
             EventBus.getDefault().post(new HideRecentsEvent(triggeredFromAltTab,
@@ -265,6 +310,11 @@
 
     @Override
     public void toggleRecents() {
+        // Skip this toggle if we are already waiting to trigger recents via alt-tab
+        if (mFastAltTabTrigger.isDozing()) {
+            return;
+        }
+
         mTriggeredFromAltTab = false;
 
         try {
@@ -283,7 +333,7 @@
                     // better than showing a janky screenshot).
                     // NOTE: Ideally, the screenshot mechanism would take the window transform into
                     // account
-                    if ((SystemClock.elapsedRealtime() - mLastToggleTime) < sMinToggleDelay) {
+                    if ((SystemClock.elapsedRealtime() - mLastToggleTime) < MIN_TOGGLE_DELAY_MS) {
                         return;
                     }
 
@@ -296,7 +346,7 @@
                 // better than showing a janky screenshot).
                 // NOTE: Ideally, the screenshot mechanism would take the window transform into
                 // account
-                if ((SystemClock.elapsedRealtime() - mLastToggleTime) < sMinToggleDelay) {
+                if ((SystemClock.elapsedRealtime() - mLastToggleTime) < MIN_TOGGLE_DELAY_MS) {
                     return;
                 }
 
@@ -305,7 +355,7 @@
                 mLastToggleTime = SystemClock.elapsedRealtime();
             }
         } catch (ActivityNotFoundException e) {
-            Console.logRawError("Failed to launch RecentAppsIntent", e);
+            Log.e(TAG, "Failed to launch RecentsActivity", e);
         }
     }
 
@@ -335,10 +385,63 @@
         // Do nothing
     }
 
-    public void showRelativeAffiliatedTask(boolean showNextTask) {
-        // Return early if there is no focused stack
+    /**
+     * Transitions to the next recent task in the stack.
+     */
+    public void showNextTask() {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        int focusedStackId = ssp.getFocusedStack();
+        RecentsTaskLoader loader = Recents.getTaskLoader();
+        RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
+        loader.preloadTasks(plan, true /* isTopTaskHome */);
+        TaskStack focusedStack = plan.getTaskStack();
+
+        // Return early if there are no tasks in the focused stack
+        if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
+
+        ActivityManager.RunningTaskInfo runningTask = ssp.getTopMostTask();
+        // Return early if there is no running task
+        if (runningTask == null) return;
+
+        // Find the task in the recents list
+        boolean isTopTaskHome = SystemServicesProxy.isHomeStack(runningTask.stackId);
+        ArrayList<Task> tasks = focusedStack.getTasks();
+        Task toTask = null;
+        ActivityOptions launchOpts = null;
+        int taskCount = tasks.size();
+        for (int i = taskCount - 1; i >= 1; i--) {
+            Task task = tasks.get(i);
+            if (isTopTaskHome) {
+                toTask = tasks.get(i - 1);
+                launchOpts = ActivityOptions.makeCustomAnimation(mContext,
+                        R.anim.recents_launch_next_affiliated_task_target,
+                        R.anim.recents_fast_toggle_app_home_exit);
+                break;
+            } else if (task.key.id == runningTask.id) {
+                toTask = tasks.get(i - 1);
+                launchOpts = ActivityOptions.makeCustomAnimation(mContext,
+                        R.anim.recents_launch_prev_affiliated_task_target,
+                        R.anim.recents_launch_prev_affiliated_task_source);
+                break;
+            }
+        }
+
+        // Return early if there is no next task
+        if (toTask == null) {
+            ssp.startInPlaceAnimationOnFrontMostApplication(
+                    ActivityOptions.makeCustomInPlaceAnimation(mContext,
+                            R.anim.recents_launch_prev_affiliated_task_bounce));
+            return;
+        }
+
+        // Launch the task
+        ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.activityLabel, launchOpts);
+    }
+
+    /**
+     * Transitions to the next affiliated task.
+     */
+    public void showRelativeAffiliatedTask(boolean showNextTask) {
+        SystemServicesProxy ssp = Recents.getSystemServices();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
         loader.preloadTasks(plan, true /* isTopTaskHome */);
@@ -403,12 +506,7 @@
         MetricsLogger.count(mContext, "overview_affiliated_task_launch", 1);
 
         // Launch the task
-        if (toTask.isActive) {
-            // Bring an active task to the foreground
-            ssp.moveTaskToFront(toTask.key.id, launchOpts);
-        } else {
-            ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.activityLabel, launchOpts);
-        }
+        ssp.startActivityFromRecents(mContext, toTask.key.id, toTask.activityLabel, launchOpts);
     }
 
     public void showNextAffiliatedTask() {
@@ -518,7 +616,7 @@
         final Task toTask = new Task();
         final TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView,
                 topTask.id, toTask);
-        ForegroundThread.getHandler().post(new Runnable() {
+        ForegroundThread.getHandler().postAtFrontOfQueue(new Runnable() {
             @Override
             public void run() {
                 final Bitmap transitionBitmap = drawThumbnailTransitionBitmap(toTask, toTransform);
@@ -540,7 +638,7 @@
         return ActivityOptions.makeCustomAnimation(mContext,
                 R.anim.recents_from_unknown_enter,
                 R.anim.recents_from_unknown_exit,
-                mHandler, this);
+                mHandler, null);
     }
 
     /**
@@ -551,12 +649,12 @@
             return ActivityOptions.makeCustomAnimation(mContext,
                     R.anim.recents_from_search_launcher_enter,
                     R.anim.recents_from_search_launcher_exit,
-                    mHandler, this);
+                    mHandler, null);
         }
         return ActivityOptions.makeCustomAnimation(mContext,
                 R.anim.recents_from_launcher_enter,
                 R.anim.recents_from_launcher_exit,
-                mHandler, this);
+                mHandler, null);
     }
 
     /**
@@ -582,7 +680,7 @@
             AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
             specs.toArray(specsArray);
             return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
-                    specsArray, mHandler, this, this);
+                    specsArray, mHandler, null, this);
         } else {
             // Update the destination rect
             Task toTask = new Task();
@@ -593,7 +691,7 @@
             if (thumbnail != null) {
                 return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
                         thumbnail, (int) toTaskRect.left, (int) toTaskRect.top,
-                        (int) toTaskRect.width(), (int) toTaskRect.height(), mHandler, this);
+                        (int) toTaskRect.width(), (int) toTaskRect.height(), mHandler, null);
             }
             // If both the screenshot and thumbnail fails, then just fall back to the default transition
             return getUnknownTransitionActivityOptions();
@@ -746,8 +844,6 @@
     private void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
               ActivityOptions opts, boolean fromHome, boolean fromSearchHome, boolean fromThumbnail,
               TaskStackLayoutAlgorithm.VisibilityReport vr) {
-        mStartAnimationTriggered = false;
-
         // Update the configuration based on the launch options
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
@@ -775,16 +871,7 @@
         mCanReuseTaskStackViews = true;
     }
 
-    /**** OnAnimationStartedListener Implementation ****/
-
-    @Override
-    public void onAnimationStarted() {
-        // Notify recents to start the enter animation
-        if (!mStartAnimationTriggered) {
-            mStartAnimationTriggered = true;
-            EventBus.getDefault().post(new EnterRecentsWindowAnimationStartedEvent());
-        }
-    }
+    /**** OnAnimationFinishedListener Implementation ****/
 
     @Override
     public void onAnimationFinished() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/CancelEnterRecentsWindowAnimationEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/CancelEnterRecentsWindowAnimationEvent.java
new file mode 100644
index 0000000..7604de1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/CancelEnterRecentsWindowAnimationEvent.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.model.Task;
+
+/**
+ * This is sent when we want to cancel the enter-recents window animation for the launch task.
+ */
+public class CancelEnterRecentsWindowAnimationEvent extends EventBus.Event {
+
+    // This is set for the task that is launching, which allows us to ensure that we are not
+    // cancelling the same task animation (it will just be overwritten instead)
+    public final Task launchTask;
+
+    public CancelEnterRecentsWindowAnimationEvent(Task launchTask) {
+        this.launchTask = launchTask;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
similarity index 72%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
copy to packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
index f187178..b31f320 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
@@ -19,8 +19,10 @@
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the window animation into Recents starts.
+ * This is sent when the window animation into Recents completes.  We use this signal to know when
+ * we can start in-app animations so that they don't conflict with the window transition into
+ * Recents.
  */
-public class EnterRecentsWindowAnimationStartedEvent extends EventBus.Event {
+public class EnterRecentsWindowAnimationCompletedEvent extends EventBus.Event {
     // Simple event
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskFailedEvent.java
similarity index 84%
rename from packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
rename to packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskFailedEvent.java
index f187178..3a2d58c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskFailedEvent.java
@@ -19,8 +19,8 @@
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the window animation into Recents starts.
+ * This is sent when we fail to launch a task.
  */
-public class EnterRecentsWindowAnimationStartedEvent extends EventBus.Event {
+public class LaunchTaskFailedEvent extends EventBus.Event {
     // Simple event
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskSucceededEvent.java
similarity index 71%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
copy to packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskSucceededEvent.java
index f187178..ec5089f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationStartedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskSucceededEvent.java
@@ -19,8 +19,13 @@
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the window animation into Recents starts.
+ * This is sent when we successfully launch a task.
  */
-public class EnterRecentsWindowAnimationStartedEvent extends EventBus.Event {
-    // Simple event
+public class LaunchTaskSucceededEvent extends EventBus.Event {
+
+    public final int taskIndexFromStackFront;
+
+    public LaunchTaskSucceededEvent(int taskIndexFromStackFront) {
+        this.taskIndexFromStackFront = taskIndexFromStackFront;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ScreenPinningRequestEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ScreenPinningRequestEvent.java
index 5cb4ccf..9d96d8e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/ScreenPinningRequestEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/ScreenPinningRequestEvent.java
@@ -26,10 +26,8 @@
 public class ScreenPinningRequestEvent extends EventBus.Event {
 
     public final Context applicationContext;
-    public final SystemServicesProxy systemServicesProxy;
 
-    public ScreenPinningRequestEvent(Context context, SystemServicesProxy systemServicesProxy) {
+    public ScreenPinningRequestEvent(Context context) {
         this.applicationContext = context.getApplicationContext();
-        this.systemServicesProxy = systemServicesProxy;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Console.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Console.java
deleted file mode 100644
index 28ac9d3..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Console.java
+++ /dev/null
@@ -1,196 +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.misc;
-
-
-import android.content.ComponentCallbacks2;
-import android.content.Context;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.widget.Toast;
-
-import java.util.HashMap;
-import java.util.Map;
-
-
-public class Console {
-    // Timer
-    public static final Map<Object, Long> mTimeLogs = new HashMap<Object, Long>();
-
-    // Colors
-    public static final String AnsiReset = "\u001B[0m";
-    public static final String AnsiBlack = "\u001B[30m";
-    public static final String AnsiRed = "\u001B[31m";      // SystemUIHandshake
-    public static final String AnsiGreen = "\u001B[32m";    // MeasureAndLayout
-    public static final String AnsiYellow = "\u001B[33m";   // SynchronizeViewsWithModel
-    public static final String AnsiBlue = "\u001B[34m";     // TouchEvents, Search
-    public static final String AnsiPurple = "\u001B[35m";   // Draw
-    public static final String AnsiCyan = "\u001B[36m";     // ClickEvents
-    public static final String AnsiWhite = "\u001B[37m";
-
-    // Console enabled state
-    public static boolean Enabled = false;
-
-    /** Logs a key */
-    public static void log(String key) {
-        log(true, key, "", AnsiReset);
-    }
-
-    /** Logs a conditioned key */
-    public static void log(boolean condition, String key) {
-        if (condition) {
-            log(condition, key, "", AnsiReset);
-        }
-    }
-
-    /** Logs a key in a specific color */
-    public static void log(boolean condition, String key, Object data) {
-        if (condition) {
-            log(condition, key, data, AnsiReset);
-        }
-    }
-
-    /** Logs a key with data in a specific color */
-    public static void log(boolean condition, String key, Object data, String color) {
-        if (condition) {
-            System.out.println(color + key + AnsiReset + " " + data.toString());
-        }
-    }
-
-    /** Logs an error */
-    public static void logError(Context context, String msg) {
-        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
-        Log.e("Recents", msg);
-    }
-
-    /** Logs a raw error */
-    public static void logRawError(String msg, Exception e) {
-        Log.e("Recents", msg, e);
-    }
-
-    /** Logs a divider bar */
-    public static void logDivider(boolean condition) {
-        if (condition) {
-            System.out.println("==== [" + System.currentTimeMillis() +
-                    "] ============================================================");
-        }
-    }
-
-    /** Starts a time trace */
-    public static void logStartTracingTime(boolean condition, String key) {
-        if (condition) {
-            long curTime = System.currentTimeMillis();
-            mTimeLogs.put(key, curTime);
-            Console.log(condition, "[Recents|" + key + "]",
-                    "started @ " + curTime);
-        }
-    }
-
-    /** Continues a time trace */
-    public static void logTraceTime(boolean condition, String key, String desc) {
-        if (condition) {
-            long timeDiff = System.currentTimeMillis() - mTimeLogs.get(key);
-            Console.log(condition, "[Recents|" + key + "|" + desc + "]",
-                    "+" + timeDiff + "ms");
-        }
-    }
-
-    /** Logs a stack trace */
-    public static void logStackTrace() {
-        logStackTrace("", 99);
-    }
-
-    /** Logs a stack trace to a certain depth */
-    public static void logStackTrace(int depth) {
-        logStackTrace("", depth);
-    }
-
-    /** Logs a stack trace to a certain depth with a key */
-    public static void logStackTrace(String key, int depth) {
-        int offset = 0;
-        StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
-        String tinyStackTrace = "";
-        // Skip over the known stack trace classes
-        for (int i = 0; i < callStack.length; i++) {
-            StackTraceElement el = callStack[i];
-            String className = el.getClassName();
-            if (className.indexOf("dalvik.system.VMStack") == -1 &&
-                className.indexOf("java.lang.Thread") == -1 &&
-                className.indexOf("recents.Console") == -1) {
-                break;
-            } else {
-                offset++;
-            }
-        }
-        // Build the pretty stack trace
-        int start = Math.min(offset + depth, callStack.length);
-        int end = offset;
-        String indent = "";
-        for (int i = start - 1; i >= end; i--) {
-            StackTraceElement el = callStack[i];
-            tinyStackTrace += indent + " -> " + el.getClassName() +
-                    "[" + el.getLineNumber() + "]." + el.getMethodName();
-            if (i > end) {
-                tinyStackTrace += "\n";
-                indent += "  ";
-            }
-        }
-        log(true, key, tinyStackTrace, AnsiRed);
-    }
-
-
-    /** Returns the stringified MotionEvent action */
-    public static String motionEventActionToString(int action) {
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                return "Down";
-            case MotionEvent.ACTION_UP:
-                return "Up";
-            case MotionEvent.ACTION_MOVE:
-                return "Move";
-            case MotionEvent.ACTION_CANCEL:
-                return "Cancel";
-            case MotionEvent.ACTION_POINTER_DOWN:
-                return "Pointer Down";
-            case MotionEvent.ACTION_POINTER_UP:
-                return "Pointer Up";
-            default:
-                return "" + action;
-        }
-    }
-
-    public static String trimMemoryLevelToString(int level) {
-        switch (level) {
-            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
-                return "UI Hidden";
-            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
-                return "Running Moderate";
-            case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
-                return "Background";
-            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
-                return "Running Low";
-            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
-                return "Moderate";
-            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
-                return "Critical";
-            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
-                return "Complete";
-            default:
-                return "" + level;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java b/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
index 336d2db..dc8f547 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
@@ -29,44 +29,53 @@
     boolean mIsDozing;
     boolean mHasTriggered;
     int mDozeDurationMilliseconds;
-    Runnable mSleepRunnable;
+    Runnable mOnSleepRunnable;
 
     // Sleep-runnable
     Runnable mDozeRunnable = new Runnable() {
         @Override
         public void run() {
-            mSleepRunnable.run();
             mIsDozing = false;
             mHasTriggered = true;
+            mOnSleepRunnable.run();
         }
     };
 
-    public DozeTrigger(int dozeDurationMilliseconds, Runnable sleepRunnable) {
+    public DozeTrigger(int dozeDurationMilliseconds, Runnable onSleepRunnable) {
         mHandler = new Handler();
         mDozeDurationMilliseconds = dozeDurationMilliseconds;
-        mSleepRunnable = sleepRunnable;
+        mOnSleepRunnable = onSleepRunnable;
     }
 
-    /** Starts dozing. This also resets the trigger flag. */
+    /**
+     * Starts dozing and queues the onSleepRunnable to be called. This also resets the trigger flag.
+     */
     public void startDozing() {
         forcePoke();
         mHasTriggered = false;
     }
 
-    /** Stops dozing. */
+    /**
+     * Stops dozing and prevents the onSleepRunnable from being called.
+     */
     public void stopDozing() {
         mHandler.removeCallbacks(mDozeRunnable);
         mIsDozing = false;
     }
 
-    /** Poke this dozer to wake it up for a little bit, if it is dozing. */
+    /**
+     * Poke this dozer to wake it up if it is dozing, delaying the onSleepRunnable from being
+     * called for a for the doze duration.
+     */
     public void poke() {
         if (mIsDozing) {
             forcePoke();
         }
     }
 
-    /** Poke this dozer to wake it up for a little bit. */
+    /**
+     * Poke this dozer to wake it up even if it is not currently dozing.
+     */
     void forcePoke() {
         mHandler.removeCallbacks(mDozeRunnable);
         mHandler.postDelayed(mDozeRunnable, mDozeDurationMilliseconds);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/ForegroundThread.java b/packages/SystemUI/src/com/android/systemui/recents/misc/ForegroundThread.java
index 8dc2983..784ac4e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/ForegroundThread.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/ForegroundThread.java
@@ -28,7 +28,7 @@
     private static Handler sHandler;
 
     private ForegroundThread() {
-        super("recents.fg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
+        super("recents.fg");
     }
 
     private static void ensureThreadLocked() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
index c87a901..401b448 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
+import android.util.Log;
 
 import java.util.ArrayList;
 
@@ -28,6 +29,8 @@
  */
 public class ReferenceCountedTrigger {
 
+    private static final String TAG = "ReferenceCountedTrigger";
+
     Context mContext;
     int mCount;
     ArrayList<Runnable> mFirstIncRunnables = new ArrayList<Runnable>();
@@ -94,8 +97,7 @@
             if (mErrorRunnable != null) {
                 mErrorRunnable.run();
             } else {
-                new Throwable("Invalid ref count").printStackTrace();
-                Console.logError(mContext, "Invalid ref count");
+                Log.e(TAG, "Invalid ref count");
             }
         }
     }
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 4ee0357..0432ac9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -363,6 +363,19 @@
         }
     }
 
+    /**
+     * Cancels the current thumbnail transtion to/from Recents for the given task id.
+     */
+    public void cancelThumbnailTransition(int taskId) {
+        if (mWm == null) return;
+
+        try {
+            WindowManagerGlobal.getWindowManagerService().cancelTaskThumbnailTransition(taskId);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
     /** Returns the top task thumbnail for the given task id */
     public Bitmap getTaskThumbnail(int taskId) {
         if (mAm == null) return null;
@@ -775,8 +788,7 @@
                         taskId, INVALID_STACK_ID, options == null ? null : options.toBundle());
                 return true;
             } catch (Exception e) {
-                Console.logError(context,
-                        context.getString(R.string.recents_launch_error_message, taskName));
+                Log.e(TAG, context.getString(R.string.recents_launch_error_message, taskName), e);
             }
         }
         return false;
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 62493d6..7b04493 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -130,10 +130,9 @@
                     ? t.taskDescription.getIconFilename() : null;
 
             // Add the task to the stack
-            Task task = new Task(taskKey, (t.id != INVALID_TASK_ID), t.affiliatedTaskId,
-                    t.affiliatedTaskColor, activityLabel, contentDescription, activityIcon,
-                    activityColor, (i == (taskCount - 1)), config.lockToAppEnabled, icon,
-                    iconFilename, t.bounds);
+            Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, activityLabel,
+                    contentDescription, activityIcon, activityColor, (i == (taskCount - 1)),
+                    config.lockToAppEnabled, icon, iconFilename, t.bounds);
             task.thumbnail = loader.getAndUpdateThumbnail(taskKey, ssp, false);
             if (DEBUG) {
                 Log.d(TAG, activityLabel + " bounds: " + t.bounds);
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 12bd556b..67e18f3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -103,7 +103,6 @@
     public int colorPrimary;
     public boolean useLightOnPrimaryColor;
     public Bitmap thumbnail;
-    public boolean isActive;
     public boolean lockToThisTask;
     public boolean lockToTaskEnabled;
     public Bitmap icon;
@@ -116,7 +115,7 @@
         // Do nothing
     }
 
-    public Task(TaskKey key, boolean isActive, int taskAffiliation, int taskAffiliationColor,
+    public Task(TaskKey key, int taskAffiliation, int taskAffiliationColor,
                 String activityTitle, String contentDescription, Drawable activityIcon,
                 int colorPrimary, boolean lockToThisTask, boolean lockToTaskEnabled, Bitmap icon,
                 String iconFilename, Rect bounds) {
@@ -131,7 +130,6 @@
         this.colorPrimary = hasAffiliationGroupColor ? taskAffiliationColor : colorPrimary;
         this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary,
                 Color.WHITE) > 3f;
-        this.isActive = isActive;
         this.lockToThisTask = lockToTaskEnabled && lockToThisTask;
         this.lockToTaskEnabled = lockToTaskEnabled;
         this.icon = icon;
@@ -149,7 +147,6 @@
         this.activityIcon = o.activityIcon;
         this.colorPrimary = o.colorPrimary;
         this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
-        this.isActive = o.isActive;
         this.lockToThisTask = o.lockToThisTask;
         this.lockToTaskEnabled = o.lockToTaskEnabled;
     }
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 495c8fd..6734012 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -17,14 +17,12 @@
 package com.android.systemui.recents.model;
 
 import android.animation.ObjectAnimator;
-import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
-import android.util.Log;
 import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.Recents;
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 21b6bd8..70370ec 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -36,7 +36,7 @@
     public AnimateableViewBounds(TaskView source, int cornerRadius) {
         mSourceView = source;
         mCornerRadius = cornerRadius;
-        setClipBottom(getClipBottom());
+        setClipBottom(getClipBottom(), false /* force */);
     }
 
     @Override
@@ -57,8 +57,8 @@
     }
 
     /** Sets the bottom clip. */
-    public void setClipBottom(int bottom) {
-        if (bottom != mClipRect.bottom) {
+    public void setClipBottom(int bottom, boolean force) {
+        if (bottom != mClipRect.bottom || force) {
             mClipRect.bottom = bottom;
             mSourceView.invalidateOutline();
             updateClipBounds();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
new file mode 100644
index 0000000..85b8fcf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -0,0 +1,331 @@
+/*
+ * 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.annotation.Nullable;
+import android.app.ActivityOptions;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.AppTransitionAnimationSpec;
+import android.view.IAppTransitionAnimationSpecsFuture;
+import android.view.WindowManagerGlobal;
+import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
+import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
+import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.model.TaskStack;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.INVALID_STACK_ID;
+
+/**
+ * A helper class to create transitions to/from Recents
+ */
+public class RecentsTransitionHelper {
+
+    private static final String TAG = "RecentsTransitionHelper";
+    private static final boolean DEBUG = false;
+
+    /**
+     * Special value for {@link #mAppTransitionAnimationSpecs}: Indicate that we are currently
+     * waiting for the specs to be retrieved.
+     */
+    private static final List<AppTransitionAnimationSpec> SPECS_WAITING = new ArrayList<>();
+
+    @GuardedBy("this")
+    private List<AppTransitionAnimationSpec> mAppTransitionAnimationSpecs = SPECS_WAITING;
+
+    private Context mContext;
+    private Handler mHandler;
+    private TaskViewTransform mTmpTransform = new TaskViewTransform();
+
+    private Runnable mStartScreenPinningRunnable = new Runnable() {
+        @Override
+        public void run() {
+            EventBus.getDefault().send(new ScreenPinningRequestEvent(mContext));
+        }
+    };
+
+    public RecentsTransitionHelper(Context context, Handler handler) {
+        mContext = context;
+        mHandler = handler;
+    }
+
+    /**
+     * Launches the specified {@link Task}.
+     */
+    public void launchTaskFromRecents(final TaskStack stack, @Nullable final Task task,
+            final TaskStackView stackView, final TaskView taskView,
+            final boolean lockToTask, final Rect bounds, int destinationStack) {
+        final ActivityOptions opts = ActivityOptions.makeBasic();
+        if (bounds != null) {
+            opts.setBounds(bounds.isEmpty() ? null : bounds);
+        }
+
+        final ActivityOptions.OnAnimationStartedListener animStartedListener;
+        final IAppTransitionAnimationSpecsFuture transitionFuture;
+        if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
+                task.thumbnail.getHeight() > 0) {
+            transitionFuture = getAppTransitionFuture(task, stackView, destinationStack);
+            animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
+                @Override
+                public void onAnimationStarted() {
+                    // If we are launching into another task, cancel the previous task's
+                    // window transition
+                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
+
+                    if (lockToTask) {
+                        // Request screen pinning after the animation runs
+                        mHandler.postDelayed(mStartScreenPinningRunnable, 350);
+                    }
+                }
+            };
+        } else {
+            // This is only the case if the task is not on screen (scrolled offscreen for example)
+            transitionFuture = null;
+            animStartedListener = null;
+        }
+
+        if (taskView == null) {
+            // If there is no task view, then we do not need to worry about animating out occluding
+            // task views, and we can launch immediately
+            startTaskActivity(stack, task, taskView, opts, transitionFuture, animStartedListener);
+        } else {
+            if (task.group != null && !task.group.isFrontMostTask(task)) {
+                stackView.startLaunchTaskAnimation(taskView, new Runnable() {
+                    @Override
+                    public void run() {
+                        startTaskActivity(stack, task, taskView, opts, transitionFuture,
+                                animStartedListener);
+                    }
+                }, lockToTask);
+            } else {
+                stackView.startLaunchTaskAnimation(taskView, null, lockToTask);
+                startTaskActivity(stack, task, taskView, opts, transitionFuture,
+                        animStartedListener);
+            }
+        }
+    }
+
+    /**
+     * Starts the activity for the launch task.
+     *
+     * @param taskView this is the {@link TaskView} that we are launching from. This can be null if
+     *                 we are toggling recents and the launch-to task is now offscreen.
+     */
+    private void startTaskActivity(TaskStack stack, Task task, @Nullable TaskView taskView,
+            ActivityOptions opts, IAppTransitionAnimationSpecsFuture transitionFuture,
+            final ActivityOptions.OnAnimationStartedListener animStartedListener) {
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        if (ssp.startActivityFromRecents(mContext, task.key.id, task.activityLabel, opts)) {
+            // Keep track of the index of the task launch
+            int taskIndexFromFront = 0;
+            int taskIndex = stack.indexOfTask(task);
+            if (taskIndex > -1) {
+                taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
+            }
+            EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
+        } else {
+            // Dismiss the task if we fail to launch it
+            EventBus.getDefault().send(new DismissTaskViewEvent(task, taskView));
+
+            // Keep track of failed launches
+            EventBus.getDefault().send(new LaunchTaskFailedEvent());
+        }
+        if (transitionFuture != null) {
+            IRemoteCallback.Stub callback = null;
+            if (animStartedListener != null) {
+                callback = new IRemoteCallback.Stub() {
+                    @Override
+                    public void sendResult(Bundle data) throws RemoteException {
+                        mHandler.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                if (animStartedListener != null) {
+                                    animStartedListener.onAnimationStarted();
+                                }
+                            }
+                        });
+                    }
+                };
+            }
+            try {
+                WindowManagerGlobal.getWindowManagerService()
+                        .overridePendingAppTransitionMultiThumbFuture(transitionFuture,
+                                callback, true /* scaleUp */);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to override transition: " + e);
+            }
+        }
+    }
+
+    /**
+     * Creates a future which will later be queried for animation specs for this current transition.
+     */
+    private IAppTransitionAnimationSpecsFuture getAppTransitionFuture(final Task task,
+            final TaskStackView stackView, final int destinationStack) {
+        return new IAppTransitionAnimationSpecsFuture.Stub() {
+            @Override
+            public AppTransitionAnimationSpec[] get() throws RemoteException {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        synchronized (RecentsTransitionHelper.this) {
+                            mAppTransitionAnimationSpecs = composeAnimationSpecs(task, stackView,
+                                    destinationStack);
+                            RecentsTransitionHelper.this.notifyAll();
+                        }
+                    }
+                });
+                synchronized (RecentsTransitionHelper.this) {
+                    while (mAppTransitionAnimationSpecs == SPECS_WAITING) {
+                        try {
+                            RecentsTransitionHelper.this.wait();
+                        } catch (InterruptedException e) {}
+                    }
+                    if (mAppTransitionAnimationSpecs == null) {
+                        return null;
+                    }
+                    AppTransitionAnimationSpec[] specs
+                            = new AppTransitionAnimationSpec[mAppTransitionAnimationSpecs.size()];
+                    mAppTransitionAnimationSpecs.toArray(specs);
+                    mAppTransitionAnimationSpecs = SPECS_WAITING;
+                    return specs;
+                }
+            }
+        };
+    }
+
+    /**
+     * Composes the animation specs for all the tasks in the target stack.
+     */
+    private List<AppTransitionAnimationSpec> composeAnimationSpecs(final Task task,
+            final TaskStackView stackView, final int destinationStack) {
+        // Ensure we have a valid target stack id
+        final int targetStackId = destinationStack != INVALID_STACK_ID ?
+                destinationStack : task.key.stackId;
+        if (targetStackId != FREEFORM_WORKSPACE_STACK_ID
+                && targetStackId != FULLSCREEN_WORKSPACE_STACK_ID) {
+            return null;
+        }
+
+        // Calculate the offscreen task rect (for tasks that are not backed by views)
+        float stackScroll = stackView.getScroller().getStackScroll();
+        TaskView taskView = stackView.getChildViewForTask(task);
+        TaskStackLayoutAlgorithm layoutAlgorithm = stackView.getStackAlgorithm();
+        Rect offscreenTaskRect = new Rect(layoutAlgorithm.mTaskRect);
+        offscreenTaskRect.offsetTo(offscreenTaskRect.left,
+                layoutAlgorithm.mCurrentStackRect.bottom);
+
+        // If this is a full screen stack, the transition will be towards the single, full screen
+        // task. We only need the transition spec for this task.
+        List<AppTransitionAnimationSpec> specs = new ArrayList<>();
+        if (targetStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
+            if (taskView == null) {
+                specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
+            } else {
+                layoutAlgorithm.getStackTransform(task, stackScroll, mTmpTransform, null);
+                specs.add(composeAnimationSpec(taskView, mTmpTransform, true /* addHeaderBitmap */));
+            }
+            return specs;
+        }
+
+        // Otherwise, for freeform tasks, create a new animation spec for each task we have to
+        // launch
+        TaskStack stack = stackView.getStack();
+        ArrayList<Task> tasks = stack.getTasks();
+        int taskCount = tasks.size();
+        for (int i = taskCount - 1; i >= 0; i--) {
+            Task t = tasks.get(i);
+            if (t.isFreeformTask() || targetStackId == FREEFORM_WORKSPACE_STACK_ID) {
+                TaskView tv = stackView.getChildViewForTask(t);
+                if (tv == null) {
+                    // TODO: Create a different animation task rect for this case (though it should
+                    //       never happen)
+                    specs.add(composeOffscreenAnimationSpec(t, offscreenTaskRect));
+                } else {
+                    layoutAlgorithm.getStackTransform(task, stackScroll, mTmpTransform, null);
+                    specs.add(composeAnimationSpec(tv, mTmpTransform, true /* addHeaderBitmap */));
+                }
+            }
+        }
+
+        return specs;
+    }
+
+    /**
+     * Composes a single animation spec for the given {@link Task}
+     */
+    private static AppTransitionAnimationSpec composeOffscreenAnimationSpec(Task task,
+            Rect taskRect) {
+        return new AppTransitionAnimationSpec(task.key.id, null, taskRect);
+    }
+
+    /**
+     * Composes a single animation spec for the given {@link TaskView}
+     */
+    private static AppTransitionAnimationSpec composeAnimationSpec(TaskView taskView,
+            TaskViewTransform transform, boolean addHeaderBitmap) {
+        // Disable any focused state before we draw the header
+        // Upfront the processing of the thumbnail
+        if (taskView.isFocusedTask()) {
+            taskView.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
+        }
+
+        Bitmap b = null;
+        if (addHeaderBitmap) {
+            float scale = transform.scale;
+            int fromHeaderWidth = (int) (taskView.mHeaderView.getMeasuredWidth() * scale);
+            int fromHeaderHeight = (int) (taskView.mHeaderView.getMeasuredHeight() * scale);
+            b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
+                    Bitmap.Config.ARGB_8888);
+
+            if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
+                b.eraseColor(0xFFff0000);
+            } else {
+                Canvas c = new Canvas(b);
+                c.scale(scale, scale);
+                taskView.mHeaderView.draw(c);
+                c.setBitmap(null);
+            }
+            b = b.createAshmemBitmap();
+        }
+
+        Rect taskRect = new Rect();
+        transform.rect.round(taskRect);
+        return new AppTransitionAnimationSpec(taskView.getTask().key.id, b, taskRect);
+    }
+}
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 1f80460..e37b7dc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,40 +16,31 @@
 
 package com.android.systemui.recents.views;
 
-import android.app.ActivityOptions;
 import android.content.Context;
-import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.IRemoteCallback;
-import android.os.RemoteException;
+import android.os.Handler;
 import android.util.ArraySet;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
 import android.view.AppTransitionAnimationSpec;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowInsets;
-import android.view.WindowManagerGlobal;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
-import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivity;
-import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.RecentsAppWidgetHostView;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
-import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
-import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
@@ -60,8 +51,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 
 /**
@@ -73,24 +62,22 @@
     private static final String TAG = "RecentsView";
     private static final boolean DEBUG = false;
 
-    private static final boolean ADD_HEADER_BITMAP = true;
     private int mStackViewVisibility = View.VISIBLE;
 
     /** The RecentsView callbacks */
     public interface RecentsViewCallbacks {
-        public void onTaskViewClicked();
-        public void onTaskLaunchFailed();
         public void onAllTaskViewsDismissed();
-        public void runAfterPause(Runnable r);
     }
 
     LayoutInflater mInflater;
+    Handler mHandler;
 
     ArrayList<TaskStack> mStacks;
     TaskStackView mTaskStackView;
     RecentsAppWidgetHostView mSearchBar;
     RecentsViewCallbacks mCb;
 
+    RecentsTransitionHelper mTransitionHelper;
     RecentsViewTouchHandler mTouchHandler;
     DragView mDragView;
     TaskStack.DockState[] mVisibleDockStates = {
@@ -120,6 +107,8 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         setWillNotDraw(false);
         mInflater = LayoutInflater.from(context);
+        mHandler = new Handler();
+        mTransitionHelper = new RecentsTransitionHelper(getContext(), mHandler);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_slow_in);
         mTouchHandler = new RecentsViewTouchHandler(this);
@@ -184,17 +173,12 @@
     public boolean launchFocusedTask() {
         if (mTaskStackView != null) {
             TaskStack stack = mTaskStackView.getStack();
-            // Iterate the stack views and try and find the focused task
-            List<TaskView> taskViews = mTaskStackView.getTaskViews();
-            int taskViewCount = taskViews.size();
-            for (int j = 0; j < taskViewCount; j++) {
-                TaskView tv = taskViews.get(j);
-                Task task = tv.getTask();
-                if (tv.isFocusedTask()) {
-                    onTaskViewClicked(mTaskStackView, tv, stack, task, false, false, null,
-                            INVALID_STACK_ID);
-                    return true;
-                }
+            Task task = mTaskStackView.getFocusedTask();
+            if (task != null) {
+                TaskView taskView = mTaskStackView.getChildViewForTask(task);
+                onTaskViewClicked(mTaskStackView, taskView, stack, task, false, null,
+                        INVALID_STACK_ID);
+                return true;
             }
         }
         return false;
@@ -210,7 +194,7 @@
             for (int j = 0; j < taskViewCount; j++) {
                 TaskView tv = taskViews.get(j);
                 if (tv.getTask() == task) {
-                    onTaskViewClicked(mTaskStackView, tv, stack, task, false, taskBounds != null,
+                    onTaskViewClicked(mTaskStackView, tv, stack, task, false,
                             taskBounds, destinationStack);
                     return true;
                 }
@@ -240,6 +224,9 @@
         }
         ctx.postAnimationTrigger.decrement();
 
+        // If we are going home, cancel the previous task's window transition
+        EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
+
         // Notify of the exit animation
         EventBus.getDefault().send(new DismissRecentsToHomeAnimationStarted());
     }
@@ -412,297 +399,14 @@
         }
     }
 
-    private void postDrawHeaderThumbnailTransitionRunnable(final TaskStackView view,
-            final TaskView clickedView, final int offsetX, final int offsetY,
-            final float stackScroll,
-            final ActivityOptions.OnAnimationStartedListener animStartedListener,
-            final int destinationStack) {
-        Runnable r = new Runnable() {
-            @Override
-            public void run() {
-                overrideDrawHeaderThumbnailTransition(view, clickedView, offsetX, offsetY,
-                        stackScroll, animStartedListener, destinationStack);
-
-            }
-        };
-
-        mCb.runAfterPause(r);
-    }
-
-    private void overrideDrawHeaderThumbnailTransition(TaskStackView stackView,
-            TaskView clickedTask, int offsetX, int offsetY, float stackScroll,
-            final ActivityOptions.OnAnimationStartedListener animStartedListener,
-            int destinationStack) {
-        List<AppTransitionAnimationSpec> specs = getAppTransitionAnimationSpecs(stackView,
-                clickedTask, offsetX, offsetY, stackScroll, destinationStack);
-        if (specs == null) {
-            return;
-        }
-
-        IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
-            @Override
-            public void sendResult(Bundle data) throws RemoteException {
-                post(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (animStartedListener != null) {
-                            animStartedListener.onAnimationStarted();
-                        }
-                    }
-                });
-            }
-        };
-
-        AppTransitionAnimationSpec[] specsArray =
-                new AppTransitionAnimationSpec[specs.size()];
-        try {
-            WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionMultiThumb(
-                    specs.toArray(specsArray), callback, null, true /* scaleUp */);
-
-        } catch (RemoteException e) {
-            Log.w(TAG, "Error overriding app transition", e);
-        }
-    }
-
-    private List<AppTransitionAnimationSpec> getAppTransitionAnimationSpecs(TaskStackView stackView,
-            TaskView clickedTask, int offsetX, int offsetY, float stackScroll,
-            int destinationStack) {
-        final int targetStackId = destinationStack != INVALID_STACK_ID ?
-                destinationStack : clickedTask.getTask().key.stackId;
-        if (targetStackId != FREEFORM_WORKSPACE_STACK_ID
-                && targetStackId != FULLSCREEN_WORKSPACE_STACK_ID) {
-            return null;
-        }
-        // If this is a full screen stack, the transition will be towards the single, full screen
-        // task. We only need the transition spec for this task.
-        List<AppTransitionAnimationSpec> specs = new ArrayList<>();
-        if (targetStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
-            specs.add(createThumbnailHeaderAnimationSpec(
-                    stackView, offsetX, offsetY, stackScroll, clickedTask,
-                    clickedTask.getTask().key.id, ADD_HEADER_BITMAP));
-            return specs;
-        }
-        // This is a free form stack or full screen stack, so there will be multiple windows
-        // animating from thumbnails. We need transition animation specs for all of them.
-
-        // We will use top and bottom task views as a base for tasks, that aren't visible on the
-        // screen. This is necessary for cascade recents list, where some of the tasks might be
-        // hidden.
-        List<TaskView> taskViews = stackView.getTaskViews();
-        int childCount = taskViews.size();
-        TaskView topChild = taskViews.get(0);
-        TaskView bottomChild = taskViews.get(childCount - 1);
-        SparseArray<TaskView> taskViewsByTaskId = new SparseArray<>();
-        for (int i = 0; i < childCount; i++) {
-            TaskView taskView = taskViews.get(i);
-            taskViewsByTaskId.put(taskView.getTask().key.id, taskView);
-        }
-
-        TaskStack stack = stackView.getStack();
-        // We go through all tasks now and for each generate transition animation spec. If there is
-        // a view associated with a task, we use that view as a base for the animation. If there
-        // isn't, we use bottom or top view, depending on which one would be closer to the task
-        // view if it existed.
-        ArrayList<Task> tasks = stack.getTasks();
-        boolean passedClickedTask = false;
-        for (int i = 0, n = tasks.size(); i < n; i++) {
-            Task task = tasks.get(i);
-            TaskView taskView = taskViewsByTaskId.get(task.key.id);
-            if (taskView != null) {
-                specs.add(createThumbnailHeaderAnimationSpec(stackView, offsetX, offsetY,
-                        stackScroll, taskView, taskView.getTask().key.id, ADD_HEADER_BITMAP));
-                if (taskView == clickedTask) {
-                    passedClickedTask = true;
-                }
-            } else {
-                taskView = passedClickedTask ? bottomChild : topChild;
-                specs.add(createThumbnailHeaderAnimationSpec(stackView, offsetX, offsetY,
-                        stackScroll, taskView, task.key.id, !ADD_HEADER_BITMAP));
-            }
-        }
-
-        return specs;
-    }
-
-    private AppTransitionAnimationSpec createThumbnailHeaderAnimationSpec(TaskStackView stackView,
-            int offsetX, int offsetY, float stackScroll, TaskView tv, int taskId,
-            boolean addHeaderBitmap) {
-        // Disable any focused state before we draw the header
-        // Upfront the processing of the thumbnail
-        if (tv.isFocusedTask()) {
-            tv.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
-        }
-        TaskViewTransform transform = new TaskViewTransform();
-        transform = stackView.getStackAlgorithm().getStackTransform(tv.mTask, stackScroll,
-                transform, null);
-
-        float scale = tv.getScaleX();
-        int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
-        int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
-
-        Bitmap b = null;
-        if (addHeaderBitmap) {
-            b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
-                    Bitmap.Config.ARGB_8888);
-
-            if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
-                b.eraseColor(0xFFff0000);
-            } else {
-                Canvas c = new Canvas(b);
-                c.scale(tv.getScaleX(), tv.getScaleY());
-                tv.mHeaderView.draw(c);
-                c.setBitmap(null);
-
-            }
-            b = b.createAshmemBitmap();
-        }
-
-        int[] pts = new int[2];
-        tv.getLocationOnScreen(pts);
-
-        final int left = pts[0] + offsetX;
-        final int top = pts[1] + offsetY;
-        final Rect rect = new Rect(left, top, left + (int) transform.rect.width(),
-                top + (int) transform.rect.height());
-
-        return new AppTransitionAnimationSpec(taskId, b, rect);
-    }
-
-    /**
-     * Cancels any running window transitions for the launched task (the task animating into
-     * Recents).
-     */
-    private void cancelLaunchedTaskWindowTransition(final Task task) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        if (launchState.launchedToTaskId != -1 &&
-                launchState.launchedToTaskId != task.key.id) {
-            ssp.cancelWindowTransition(launchState.launchedToTaskId);
-        }
-    }
-
     /**** TaskStackView.TaskStackCallbacks Implementation ****/
 
     @Override
     public void onTaskViewClicked(final TaskStackView stackView, final TaskView tv,
             final TaskStack stack, final Task task, final boolean lockToTask,
-            final boolean boundsValid, final Rect bounds, int destinationStack) {
-        // Notify any callbacks of the launching of a new task
-        if (mCb != null) {
-            mCb.onTaskViewClicked();
-        }
-
-        // Upfront the processing of the thumbnail
-        TaskViewTransform transform = new TaskViewTransform();
-        View sourceView;
-        int offsetX = 0;
-        int offsetY = 0;
-        float stackScroll = stackView.getScroller().getStackScroll();
-        if (tv == null) {
-            // If there is no actual task view, then use the stack view as the source view
-            // and then offset to the expected transform rect, but bound this to just
-            // outside the display rect (to ensure we don't animate from too far away)
-            sourceView = stackView;
-            offsetX = (int) transform.rect.left;
-            offsetY = getMeasuredHeight();
-        } else {
-            sourceView = tv.mThumbnailView;
-        }
-
-        // Compute the thumbnail to scale up from
-        final SystemServicesProxy ssp = Recents.getSystemServices();
-        boolean screenPinningRequested = false;
-        ActivityOptions opts = null;
-        ActivityOptions.OnAnimationStartedListener animStartedListener = null;
-        if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
-                task.thumbnail.getHeight() > 0) {
-            animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
-                @Override
-                public void onAnimationStarted() {
-                    // If we are launching into another task, cancel the previous task's
-                    // window transition
-                    cancelLaunchedTaskWindowTransition(task);
-
-                    if (lockToTask) {
-                        // Request screen pinning after the animation runs
-                        postDelayed(new Runnable() {
-                            @Override
-                            public void run() {
-                                EventBus.getDefault().send(new ScreenPinningRequestEvent(
-                                        getContext(), ssp));
-                            }
-                        }, 350);
-                    }
-                }
-            };
-            postDrawHeaderThumbnailTransitionRunnable(stackView, tv, offsetX, offsetY, stackScroll,
-                    animStartedListener, destinationStack);
-            opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView,
-                    Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).createAshmemBitmap(),
-                    offsetX, offsetY, (int) transform.rect.width(), (int) transform.rect.height(),
-                    sourceView.getHandler(), animStartedListener);
-            screenPinningRequested = true;
-        } else {
-            opts = ActivityOptions.makeBasic();
-        }
-        if (boundsValid) {
-            opts.setBounds(bounds.isEmpty() ? null : bounds);
-        }
-        final ActivityOptions launchOpts = opts;
-        final boolean finalScreenPinningRequested = screenPinningRequested;
-        final Runnable launchRunnable = new Runnable() {
-            @Override
-            public void run() {
-                if (task.isActive) {
-                    // Bring an active task to the foreground
-                    ssp.moveTaskToFront(task.key.id, launchOpts);
-                } else {
-                    if (ssp.startActivityFromRecents(getContext(), task.key.id, task.activityLabel,
-                            launchOpts)) {
-                        if (!finalScreenPinningRequested) {
-                            // If we have not requested this already to be run after the window
-                            // transition, then just run it now
-                            EventBus.getDefault().send(new ScreenPinningRequestEvent(
-                                    getContext(), ssp));
-                        }
-                    } else {
-                        // Dismiss the task and return the user to home if we fail to
-                        // launch the task
-                        EventBus.getDefault().send(new DismissTaskViewEvent(task, tv));
-                        if (mCb != null) {
-                            mCb.onTaskLaunchFailed();
-                        }
-
-                        // Keep track of failed launches
-                        MetricsLogger.count(getContext(), "overview_task_launch_failed", 1);
-                    }
-                }
-            }
-        };
-
-        // Keep track of the index of the task launch
-        int taskIndexFromFront = 0;
-        int taskIndex = stack.indexOfTask(task);
-        if (taskIndex > -1) {
-            taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
-        }
-        MetricsLogger.histogram(getContext(), "overview_task_launch_index", taskIndexFromFront);
-
-        // Launch the app right away if there is no task view, otherwise, animate the icon out first
-        if (tv == null) {
-            launchRunnable.run();
-        } else {
-            if (task.group != null && !task.group.isFrontMostTask(task)) {
-                // For affiliated tasks that are behind other tasks, we must animate the front cards
-                // out of view before starting the task transition
-                stackView.startLaunchTaskAnimation(tv, launchRunnable, lockToTask);
-            } else {
-                // Otherwise, we can start the task transition immediately
-                stackView.startLaunchTaskAnimation(tv, null, lockToTask);
-                launchRunnable.run();
-            }
-        }
+            final Rect bounds, int destinationStack) {
+        mTransitionHelper.launchTaskFromRecents(stack, task, stackView, tv, lockToTask, bounds,
+                destinationStack);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
index c4e2d8a..5a09ee4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -26,7 +26,7 @@
 import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationStartedEvent;
+import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
 
 /** Manages the scrims for the various system bars. */
 public class SystemBarScrimViews {
@@ -81,21 +81,11 @@
     /**
      * Starts animating the scrim views when entering Recents.
      */
-    public final void onBusEvent(EnterRecentsWindowAnimationStartedEvent event) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        int transitionEnterFromAppDelay = mContext.getResources().getInteger(
-                R.integer.recents_enter_from_app_transition_duration);
-        int transitionEnterFromHomeDelay = mContext.getResources().getInteger(
-                R.integer.recents_enter_from_home_transition_duration);
-
+    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
         if (mHasStatusBarScrim && mShouldAnimateStatusBarScrim) {
             mStatusBarScrimView.setTranslationY(-mStatusBarScrimView.getMeasuredHeight());
             mStatusBarScrimView.animate()
                     .translationY(0)
-                    .setStartDelay(launchState.launchedFromHome ?
-                            transitionEnterFromHomeDelay :
-                            transitionEnterFromAppDelay)
                     .setDuration(mNavBarScrimEnterDuration)
                     .setInterpolator(mQuintOutInterpolator)
                     .withStartAction(new Runnable() {
@@ -110,9 +100,6 @@
             mNavBarScrimView.setTranslationY(mNavBarScrimView.getMeasuredHeight());
             mNavBarScrimView.animate()
                     .translationY(0)
-                    .setStartDelay(launchState.launchedFromHome ?
-                            transitionEnterFromHomeDelay :
-                            transitionEnterFromAppDelay)
                     .setDuration(mNavBarScrimEnterDuration)
                     .setInterpolator(mQuintOutInterpolator)
                     .withStartAction(new Runnable() {
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 7f5c768..51091c3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -31,7 +31,6 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 
 
 /**
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 fc3a681..a57ac9d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -34,7 +34,6 @@
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
-import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivity;
 import com.android.systemui.recents.RecentsActivityLaunchState;
@@ -80,7 +79,7 @@
     /** The TaskView callbacks */
     interface TaskStackViewCallbacks {
         public void onTaskViewClicked(TaskStackView stackView, TaskView tv, TaskStack stack, Task t,
-                boolean lockToTask, boolean boundsValid, Rect bounds, int destinationStack);
+                boolean lockToTask, Rect bounds, int destinationStack);
         public void onAllTaskViewsDismissed(ArrayList<Task> removedTasks);
         public void onTaskStackFilterTriggered();
         public void onTaskStackUnfilterTriggered();
@@ -117,6 +116,7 @@
     List<TaskView> mImmutableTaskViews = new ArrayList<>();
     LayoutInflater mInflater;
     boolean mLayersDisabled;
+    boolean mTouchExplorationEnabled;
 
     Interpolator mFastOutSlowInInterpolator;
 
@@ -184,6 +184,8 @@
 
     @Override
     protected void onAttachedToWindow() {
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
         EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
         super.onAttachedToWindow();
     }
@@ -228,6 +230,42 @@
         return mImmutableTaskViews;
     }
 
+    /**
+     * Returns the front most task view.
+     *
+     * @param stackTasksOnly if set, will return the front most task view in the stack (by default
+     *                       the front most task view will be freeform since they are placed above
+     *                       stack tasks)
+     */
+    private TaskView getFrontMostTaskView(boolean stackTasksOnly) {
+        List<TaskView> taskViews = getTaskViews();
+        int taskViewCount = taskViews.size();
+        for (int i = taskViewCount - 1; i >= 0; i--) {
+            TaskView tv = taskViews.get(i);
+            Task task = tv.getTask();
+            if (stackTasksOnly && task.isFreeformTask()) {
+                continue;
+            }
+            return tv;
+        }
+        return null;
+    }
+
+    /**
+     * Finds the child view given a specific {@param task}.
+     */
+    public TaskView getChildViewForTask(Task t) {
+        List<TaskView> taskViews = getTaskViews();
+        int taskViewCount = taskViews.size();
+        for (int i = 0; i < taskViewCount; i++) {
+            TaskView tv = taskViews.get(i);
+            if (tv.getTask() == t) {
+                return tv;
+            }
+        }
+        return null;
+    }
+
     /** Resets this TaskStackView for reuse. */
     void reset() {
         // Reset the focused task
@@ -288,19 +326,6 @@
         }
     }
 
-    /** Finds the child view given a specific task. */
-    public TaskView getChildViewForTask(Task t) {
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            if (tv.getTask() == t) {
-                return tv;
-            }
-        }
-        return null;
-    }
-
     /** Returns the stack algorithm for this task stack. */
     public TaskStackLayoutAlgorithm getStackAlgorithm() {
         return mLayoutAlgorithm;
@@ -403,7 +428,7 @@
                         visibleStackRange[1] <= taskIndex && taskIndex <= visibleStackRange[0]) {
                     mTmpTaskViewMap.put(task, tv);
                 } else {
-                    if (tv.isFocusedTask()) {
+                    if (mTouchExplorationEnabled && tv.isFocusedTask()) {
                         wasLastFocusedTaskAnimated = tv.isFocusAnimated();
                         lastFocusedTaskIndex = taskIndex;
                         resetFocusedTask();
@@ -516,7 +541,7 @@
     /**
      * Updates the clip for each of the task views from back to front.
      */
-    void clipTaskViews() {
+    void clipTaskViews(boolean forceUpdate) {
         // Update the clip on each task child
         List<TaskView> taskViews = getTaskViews();
         TaskView tmpTv = null;
@@ -553,7 +578,7 @@
                     }
                 }
             }
-            tv.getViewBounds().setClipBottom(clipBottom);
+            tv.getViewBounds().setClipBottom(clipBottom, forceUpdate);
         }
         mStackViewsClipDirty = false;
     }
@@ -635,13 +660,49 @@
     /**
      * Sets the focused task relative to the currently focused task.
      *
+     * @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.
      */
-    public void setRelativeFocusedTask(boolean forward, boolean animated) {
-        // Find the next index to focus
-        int newIndex = mFocusedTaskIndex + (forward ? -1 : 1);
-        setFocusedTask(newIndex, true, animated);
+    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated) {
+        int newIndex = -1;
+        if (mFocusedTaskIndex != -1) {
+            if (stackTasksOnly) {
+                List<Task> tasks =  mStack.getTasks();
+                newIndex = mFocusedTaskIndex;
+                Task task = tasks.get(mFocusedTaskIndex);
+                if (task.isFreeformTask()) {
+                    // Try and focus the front most stack task
+                    TaskView tv = getFrontMostTaskView(stackTasksOnly);
+                    if (tv != null) {
+                        newIndex = mStack.indexOfTask(tv.getTask());
+                    }
+                } else {
+                    // Try the next task if it is a stack task
+                    int tmpNewIndex = mFocusedTaskIndex + (forward ? -1 : 1);
+                    if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
+                        Task t = tasks.get(tmpNewIndex);
+                        if (!t.isFreeformTask()) {
+                            newIndex = tmpNewIndex;
+                        }
+                    }
+                }
+            } else {
+                // No restrictions, lets just move to the new task
+                newIndex = mFocusedTaskIndex + (forward ? -1 : 1);
+            }
+        } else {
+            // We don't have a focused task, so focus the first visible task view
+            TaskView tv = getFrontMostTaskView(stackTasksOnly);
+            if (tv != null) {
+                newIndex = mStack.indexOfTask(tv.getTask());
+            }
+        }
+        if (newIndex != -1) {
+            setFocusedTask(newIndex, true, animated);
+        }
     }
 
     /**
@@ -658,6 +719,16 @@
         mFocusedTaskIndex = -1;
     }
 
+    /**
+     * Returns the focused task.
+     */
+    Task getFocusedTask() {
+        if (mFocusedTaskIndex != -1) {
+            return mStack.getTasks().get(mFocusedTaskIndex);
+        }
+        return null;
+    }
+
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
@@ -703,11 +774,11 @@
         }
         switch (action) {
             case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
-                setRelativeFocusedTask(true, false /* animated */);
+                setRelativeFocusedTask(true, false /* stackTasksOnly */, false /* animated */);
                 return true;
             }
             case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
-                setRelativeFocusedTask(false, false /* animated */);
+                setRelativeFocusedTask(false, false /* stackTasksOnly */, false /* animated */);
                 return true;
             }
         }
@@ -734,7 +805,7 @@
         mStackScroller.computeScroll();
         // Synchronize the views
         synchronizeStackViewsWithModel();
-        clipTaskViews();
+        clipTaskViews(false /* forceUpdate */);
         // Notify accessibility
         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
     }
@@ -838,6 +909,12 @@
             mAwaitingFirstLayout = false;
             onFirstLayout();
         }
+
+        if (changed) {
+            requestSynchronizeStackViewsWithModel();
+            synchronizeStackViewsWithModel();
+            clipTaskViews(true /* forceUpdate */);
+        }
     }
 
     /** Handler for the first layout. */
@@ -1084,7 +1161,7 @@
             TaskView frontTv = getChildViewForTask(newFrontMostTask);
             if (frontTv != null) {
                 frontTv.onTaskBound(newFrontMostTask);
-                frontTv.fadeInActionButton(0, getResources().getInteger(
+                frontTv.fadeInActionButton(getResources().getInteger(
                         R.integer.recents_task_enter_from_app_duration));
             }
         }
@@ -1269,8 +1346,7 @@
         mUIDozeTrigger.stopDozing();
 
         if (mCb != null) {
-            mCb.onTaskViewClicked(this, tv, mStack, task, lockToTask, false, null,
-                    INVALID_STACK_ID);
+            mCb.onTaskViewClicked(this, tv, mStack, task, lockToTask, null, INVALID_STACK_ID);
         }
     }
 
@@ -1324,11 +1400,11 @@
     }
 
     public final void onBusEvent(FocusNextTaskViewEvent event) {
-        setRelativeFocusedTask(true, true);
+        setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */);
     }
 
     public final void onBusEvent(FocusPreviousTaskViewEvent event) {
-        setRelativeFocusedTask(false, true);
+        setRelativeFocusedTask(false, false /* stackTasksOnly */, true /* animated */);
     }
 
     public final void onBusEvent(DismissFocusedTaskViewEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewFilterAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewFilterAlgorithm.java
index a32b242..45f573d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewFilterAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewFilterAlgorithm.java
@@ -17,7 +17,6 @@
 package com.android.systemui.recents.views;
 
 import com.android.systemui.R;
-import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.model.Task;
 
 import java.util.ArrayList;
@@ -113,7 +112,7 @@
                     tv.prepareTaskTransformForFilterTaskHidden(fromTransform);
                     tv.updateViewPropertiesToTaskTransform(fromTransform, 0);
 
-                    toTransform.startDelay = offset * Constants.Values.TaskStackView.FilterStartDelay;
+                    toTransform.startDelay = offset * 25;
                     childViewTransformsOut.put(tv, toTransform);
 
                     // Use the movement of the new views to calculate the duration of the animation
@@ -166,7 +165,7 @@
                         (int) tv.getTranslationY()));
             }
 
-            toTransform.startDelay = offset * Constants.Values.TaskStackView.FilterStartDelay;
+            toTransform.startDelay = offset * 25;
             childViewTransformsOut.put(tv, toTransform);
             offset++;
         }
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 59c9708..81c89a1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -31,6 +31,7 @@
 import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
@@ -149,6 +150,11 @@
         if (mSv.getTaskViews().size() == 0) {
             return false;
         }
+        // Short circuit while we are alt-tabbing
+        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
+        if (launchState.launchedWithAltTab) {
+            return false;
+        }
 
         final TaskStackLayoutAlgorithm layoutAlgorithm = mSv.mLayoutAlgorithm;
         int action = ev.getAction();
@@ -305,9 +311,11 @@
                     // Find the front most task and scroll the next task to the front
                     float vScroll = ev.getAxisValue(MotionEvent.AXIS_VSCROLL);
                     if (vScroll > 0) {
-                        mSv.setRelativeFocusedTask(true, false /* animated */);
+                        mSv.setRelativeFocusedTask(true, true /* stackTasksOnly */,
+                                false /* animated */);
                     } else {
-                        mSv.setRelativeFocusedTask(false, false /* animated */);
+                        mSv.setRelativeFocusedTask(false, true /* stackTasksOnly */,
+                                false /* animated */);
                     }
                     return true;
             }
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 dd1474d..cb7465d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -29,6 +29,7 @@
 import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -80,7 +81,6 @@
     boolean mTaskDataLoaded;
     boolean mIsFocused;
     boolean mIsFocusAnimated;
-    boolean mFocusAnimationsEnabled;
     boolean mClipViewInStack;
     AnimateableViewBounds mViewBounds;
 
@@ -313,10 +313,6 @@
         RecentsActivityLaunchState launchState = config.getLaunchState();
         Resources res = mContext.getResources();
         final TaskViewTransform transform = ctx.currentTaskTransform;
-        final int transitionEnterFromAppDelay = res.getInteger(
-                R.integer.recents_enter_from_app_transition_duration);
-        final int transitionEnterFromHomeDelay = res.getInteger(
-                R.integer.recents_enter_from_home_transition_duration);
         final int taskViewEnterFromAppDuration = res.getInteger(
                 R.integer.recents_task_enter_from_app_duration);
         final int taskViewEnterFromHomeDuration = res.getInteger(
@@ -332,25 +328,22 @@
                 if (Constants.DebugFlags.App.EnableThumbnailAlphaOnFrontmost) {
                     // Animate the thumbnail alpha before the dim animation (to prevent updating the
                     // hardware layer)
-                    mThumbnailView.startEnterRecentsAnimation(transitionEnterFromAppDelay,
-                            new Runnable() {
-                                @Override
-                                public void run() {
-                                    animateDimToProgress(0, taskViewEnterFromAppDuration,
-                                            ctx.postAnimationTrigger.decrementOnAnimationEnd());
-                                }
-                            });
+                    mThumbnailView.startEnterRecentsAnimation(new Runnable() {
+                            @Override
+                            public void run() {
+                                animateDimToProgress(taskViewEnterFromAppDuration,
+                                        ctx.postAnimationTrigger.decrementOnAnimationEnd());
+                            }
+                        });
                 } else {
                     // Immediately start the dim animation
-                    animateDimToProgress(transitionEnterFromAppDelay,
-                            taskViewEnterFromAppDuration,
+                    animateDimToProgress(taskViewEnterFromAppDuration,
                             ctx.postAnimationTrigger.decrementOnAnimationEnd());
                 }
                 ctx.postAnimationTrigger.increment();
 
                 // Animate the action button in
-                fadeInActionButton(transitionEnterFromAppDelay,
-                        taskViewEnterFromAppDuration);
+                fadeInActionButton(taskViewEnterFromAppDuration);
             } else {
                 // Animate the task up if it was occluding the launch target
                 if (ctx.currentTaskOccludesLaunchTarget) {
@@ -358,7 +351,6 @@
                     setAlpha(0f);
                     animate().alpha(1f)
                             .translationY(transform.translationY)
-                            .setStartDelay(transitionEnterFromAppDelay)
                             .setUpdateListener(null)
                             .setInterpolator(mFastOutSlowInInterpolator)
                             .setDuration(taskViewEnterFromHomeDuration)
@@ -377,8 +369,7 @@
         } else if (launchState.launchedFromHome) {
             // Animate the tasks up
             int frontIndex = (ctx.currentStackViewCount - ctx.currentStackViewIndex - 1);
-            int delay = transitionEnterFromHomeDelay +
-                    frontIndex * taskViewEnterFromHomeStaggerDelay;
+            int delay = frontIndex * taskViewEnterFromHomeStaggerDelay;
 
             setScaleX(transform.scale);
             setScaleY(transform.scale);
@@ -404,13 +395,12 @@
         }
     }
 
-    public void fadeInActionButton(int delay, int duration) {
+    public void fadeInActionButton(int duration) {
         // Hide the action button
         mActionButtonView.setAlpha(0f);
 
         // Animate the action button in
         mActionButtonView.animate().alpha(1f)
-                .setStartDelay(delay)
                 .setDuration(duration)
                 .setInterpolator(PhoneStatusBar.ALPHA_IN)
                 .start();
@@ -611,12 +601,11 @@
     }
 
     /** Animates the dim to the task progress. */
-    void animateDimToProgress(int delay, int duration, Animator.AnimatorListener postAnimRunnable) {
+    void animateDimToProgress(int duration, Animator.AnimatorListener postAnimRunnable) {
         // Animate the dim into view as well
         int toDim = getDimFromTaskProgress();
         if (toDim != getDim()) {
             ObjectAnimator anim = ObjectAnimator.ofInt(TaskView.this, "dim", toDim);
-            anim.setStartDelay(delay);
             anim.setDuration(duration);
             if (postAnimRunnable != null) {
                 anim.addListener(postAnimRunnable);
@@ -642,6 +631,21 @@
         setDim(getDimFromTaskProgress());
     }
 
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+        if (Constants.DebugFlags.App.EnableFastToggleRecents && mIsFocused) {
+            Paint tmpPaint = new Paint();
+            Rect tmpRect = new Rect();
+            tmpRect.set(0, 0, getWidth(), getHeight());
+            tmpPaint.setColor(0xFFFF0000);
+            tmpPaint.setStrokeWidth(35);
+            tmpPaint.setStyle(Paint.Style.STROKE);
+            canvas.drawRect(tmpRect, tmpPaint);
+        }
+    }
+
     /**** View focus state ****/
 
     /**
@@ -672,6 +676,9 @@
                 clearAccessibilityFocus();
             }
         }
+        if (Constants.DebugFlags.App.EnableFastToggleRecents) {
+            invalidate();
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index 690c297..bc50846 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -218,13 +218,13 @@
     void onFocusChanged(boolean focused) {
         if (focused) {
             if (Float.compare(getAlpha(), 1f) != 0) {
-                startFadeAnimation(1f, 0, 150, null);
+                startFadeAnimation(1f, 150, null);
             }
         } else {
             float taskViewThumbnailAlpha = getResources().getFloat(
                     R.dimen.recents_task_view_thumbnail_alpha);
             if (Float.compare(getAlpha(), taskViewThumbnailAlpha) != 0) {
-                startFadeAnimation(taskViewThumbnailAlpha, 0, 150, null);
+                startFadeAnimation(taskViewThumbnailAlpha, 150, null);
             }
         }
     }
@@ -244,10 +244,10 @@
     }
 
     /** Animates this task thumbnail as it enters Recents. */
-    void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) {
+    void startEnterRecentsAnimation(Runnable postAnimRunnable) {
         float taskViewThumbnailAlpha = getResources().getFloat(
                 R.dimen.recents_task_view_thumbnail_alpha);
-        startFadeAnimation(taskViewThumbnailAlpha, delay,
+        startFadeAnimation(taskViewThumbnailAlpha,
                 getResources().getInteger(R.integer.recents_task_enter_from_app_duration),
                 postAnimRunnable);
     }
@@ -256,14 +256,13 @@
     void startLaunchTaskAnimation(Runnable postAnimRunnable) {
         int taskViewExitToAppDuration = mContext.getResources().getInteger(
                 R.integer.recents_task_exit_to_app_duration);
-        startFadeAnimation(1f, 0, taskViewExitToAppDuration, postAnimRunnable);
+        startFadeAnimation(1f, taskViewExitToAppDuration, postAnimRunnable);
     }
 
     /** Starts a new thumbnail alpha animation. */
-    void startFadeAnimation(float finalAlpha, int delay, int duration, final Runnable postAnimRunnable) {
+    void startFadeAnimation(float finalAlpha, int duration, final Runnable postAnimRunnable) {
         Utilities.cancelAnimationWithoutCallbacks(mThumbnailAlphaAnimator);
         mThumbnailAlphaAnimator = ValueAnimator.ofFloat(mThumbnailAlpha, finalAlpha);
-        mThumbnailAlphaAnimator.setStartDelay(delay);
         mThumbnailAlphaAnimator.setDuration(duration);
         mThumbnailAlphaAnimator.setInterpolator(mFastOutSlowInInterpolator);
         mThumbnailAlphaAnimator.addUpdateListener(mThumbnailAlphaUpdateListener);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
new file mode 100644
index 0000000..dd894ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -0,0 +1,68 @@
+/*
+ * 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.stackdivider;
+
+import android.content.res.Configuration;
+import android.view.LayoutInflater;
+
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+/**
+ * Controls the docked stack divider.
+ */
+public class Divider extends SystemUI {
+    private static final String TAG = "Divider";
+    private int mDividerWindowWidth;
+    private DividerWindowManager mWindowManager;
+
+    @Override
+    public void start() {
+        mWindowManager = new DividerWindowManager(mContext);
+        mDividerWindowWidth = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_thickness);
+        update(mContext.getResources().getConfiguration());
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        update(newConfig);
+    }
+
+    private void addDivider(Configuration configuration) {
+        DividerView view = (DividerView)
+                LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
+        final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
+        final int width = landscape ? mDividerWindowWidth : MATCH_PARENT;
+        final int height = landscape ? MATCH_PARENT : mDividerWindowWidth;
+        mWindowManager.add(view, width, height);
+        view.setWindowManager(mWindowManager);
+    }
+
+    private void removeDivider() {
+        mWindowManager.remove();
+    }
+
+    private void update(Configuration configuration) {
+        removeDivider();
+        addDivider(configuration);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerSnapAlgorithm.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerSnapAlgorithm.java
new file mode 100644
index 0000000..5f983c5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerSnapAlgorithm.java
@@ -0,0 +1,130 @@
+/*
+ * 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.stackdivider;
+
+import android.content.Context;
+import android.util.DisplayMetrics;
+import android.view.DisplayInfo;
+
+import com.android.systemui.statusbar.FlingAnimationUtils;
+
+import java.util.ArrayList;
+
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+
+/**
+ * Calculates the snap targets and the snap position given a position and a velocity. All positions
+ * here are to be interpreted as the left/top edge of the divider rectangle.
+ */
+public class DividerSnapAlgorithm {
+
+    private final Context mContext;
+    private final FlingAnimationUtils mFlingAnimationUtils;
+    private final int mDividerSize;
+    private final ArrayList<SnapTarget> mTargets;
+
+    /** The first target which is still splitting the screen */
+    private final SnapTarget mFirstSplitTarget;
+
+    /** The last target which is still splitting the screen */
+    private final SnapTarget mLastSplitTarget;
+
+    private final SnapTarget mDismissStartTarget;
+    private final SnapTarget mDismissEndTarget;
+
+    public DividerSnapAlgorithm(Context ctx, FlingAnimationUtils flingAnimationUtils,
+            int dividerSize, boolean isHorizontalDivision) {
+        mContext = ctx;
+        mFlingAnimationUtils = flingAnimationUtils;
+        mDividerSize = dividerSize;
+        mTargets = calculateTargets(isHorizontalDivision);
+        mFirstSplitTarget = mTargets.get(1);
+        mLastSplitTarget = mTargets.get(mTargets.size() - 2);
+        mDismissStartTarget = mTargets.get(0);
+        mDismissEndTarget = mTargets.get(mTargets.size() - 1);
+    }
+
+    public SnapTarget calculateSnapTarget(int position, float velocity) {
+        if (Math.abs(velocity) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
+            return snap(position);
+        }
+        if (position < mFirstSplitTarget.position && velocity < 0) {
+            return mDismissStartTarget;
+        }
+        if (position > mLastSplitTarget.position && velocity > 0) {
+            return mDismissEndTarget;
+        }
+        if (velocity < 0) {
+            return mFirstSplitTarget;
+        } else {
+            return mLastSplitTarget;
+        }
+    }
+
+    private SnapTarget snap(int position) {
+        int minIndex = -1;
+        int minDistance = Integer.MAX_VALUE;
+        int size = mTargets.size();
+        for (int i = 0; i < size; i++) {
+            int distance = Math.abs(position - mTargets.get(i).position);
+            if (distance < minDistance) {
+                minIndex = i;
+                minDistance = distance;
+            }
+        }
+        return mTargets.get(minIndex);
+    }
+
+    private ArrayList<SnapTarget> calculateTargets(boolean isHorizontalDivision) {
+        ArrayList<SnapTarget> targets = new ArrayList<>();
+        DisplayMetrics info = mContext.getResources().getDisplayMetrics();
+        int dividerMax = isHorizontalDivision
+                ? info.heightPixels
+                : info.widthPixels;
+
+        // TODO: Better calculation
+        targets.add(new SnapTarget(-mDividerSize, SnapTarget.FLAG_DISMISS_START));
+        targets.add(new SnapTarget((int) (0.35f * dividerMax) - mDividerSize / 2,
+                SnapTarget.FLAG_NONE));
+        targets.add(new SnapTarget(dividerMax / 2 - mDividerSize / 2, SnapTarget.FLAG_NONE));
+        targets.add(new SnapTarget((int) (0.65f * dividerMax) - mDividerSize / 2,
+                SnapTarget.FLAG_NONE));
+        targets.add(new SnapTarget(dividerMax, SnapTarget.FLAG_DISMISS_END));
+        return targets;
+    }
+
+    /**
+     * Represents a snap target for the divider.
+     */
+    public static class SnapTarget {
+        public static final int FLAG_NONE = 0;
+
+        /** If the divider reaches this value, the left/top task should be dismissed. */
+        public static final int FLAG_DISMISS_START = 1;
+
+        /** If the divider reaches this value, the right/bottom task should be dismissed */
+        public static final int FLAG_DISMISS_END = 2;
+
+        public final int position;
+        public final int flag;
+
+        public SnapTarget(int position, int flag) {
+            this.position = position;
+            this.flag = flag;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
new file mode 100644
index 0000000..a520a33
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -0,0 +1,328 @@
+/*
+ * 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.stackdivider;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.graphics.Region.Op;
+import android.hardware.display.DisplayManager;
+import android.util.AttributeSet;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewTreeObserver.InternalInsetsInfo;
+import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
+import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+
+import com.android.systemui.R;
+import com.android.systemui.stackdivider.DividerSnapAlgorithm.SnapTarget;
+import com.android.systemui.statusbar.FlingAnimationUtils;
+
+import static android.view.PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW;
+import static android.view.PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW;
+
+/**
+ * Docked stack divider.
+ */
+public class DividerView extends FrameLayout implements OnTouchListener,
+        OnComputeInternalInsetsListener {
+
+    private static final String TAG = "DividerView";
+
+    private ImageButton mHandle;
+    private View mBackground;
+    private int mStartX;
+    private int mStartY;
+    private int mStartPosition;
+    private int mDockSide;
+    private final int[] mTempInt2 = new int[2];
+
+    private int mDividerInsets;
+    private int mDisplayWidth;
+    private int mDisplayHeight;
+    private int mDividerWindowWidth;
+    private int mDividerSize;
+    private int mTouchElevation;
+
+    private final Rect mTmpRect = new Rect();
+    private final Rect mLastResizeRect = new Rect();
+    private final WindowManagerProxy mWindowManagerProxy = new WindowManagerProxy();
+    private Interpolator mFastOutSlowInInterpolator;
+    private final Interpolator mTouchResponseInterpolator =
+            new PathInterpolator(0.3f, 0f, 0.1f, 1f);
+    private DividerWindowManager mWindowManager;
+    private VelocityTracker mVelocityTracker;
+    private FlingAnimationUtils mFlingAnimationUtils;
+
+    public DividerView(Context context) {
+        super(context);
+    }
+
+    public DividerView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mHandle = (ImageButton) findViewById(R.id.docked_divider_handle);
+        mBackground = findViewById(R.id.docked_divider_background);
+        mHandle.setOnTouchListener(this);
+        mDividerWindowWidth = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_thickness);
+        mDividerInsets = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_insets);
+        mDividerSize = mDividerWindowWidth - 2 * mDividerInsets;
+        mTouchElevation = getResources().getDimensionPixelSize(
+                R.dimen.docked_stack_divider_lift_elevation);
+        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
+                android.R.interpolator.fast_out_slow_in);
+        mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.3f);
+        updateDisplayInfo();
+        boolean landscape = getResources().getConfiguration().orientation
+                == Configuration.ORIENTATION_LANDSCAPE;
+        mHandle.setPointerShape(
+                landscape ? STYLE_HORIZONTAL_DOUBLE_ARROW : STYLE_VERTICAL_DOUBLE_ARROW);
+        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+    }
+
+    public void setWindowManager(DividerWindowManager windowManager) {
+        mWindowManager = windowManager;
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        convertToScreenCoordinates(event);
+        final int action = event.getAction() & MotionEvent.ACTION_MASK;
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mVelocityTracker = VelocityTracker.obtain();
+                mVelocityTracker.addMovement(event);
+                mStartX = (int) event.getX();
+                mStartY = (int) event.getY();
+                getLocationOnScreen(mTempInt2);
+                mDockSide = mWindowManagerProxy.getDockSide();
+                if (isHorizontalDivision()) {
+                    mStartPosition = mTempInt2[1] + mDividerInsets;
+                } else {
+                    mStartPosition = mTempInt2[0] + mDividerInsets;
+                }
+                if (mDockSide != WindowManager.DOCKED_INVALID) {
+                    mWindowManagerProxy.setResizing(true);
+                    mWindowManager.setSlippery(false);
+                    liftBackground();
+                    return true;
+                } else {
+                    return false;
+                }
+            case MotionEvent.ACTION_MOVE:
+                mVelocityTracker.addMovement(event);
+                int x = (int) event.getX();
+                int y = (int) event.getY();
+                if (mDockSide != WindowManager.DOCKED_INVALID) {
+                    resizeStack(calculatePosition(x, y));
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mVelocityTracker.addMovement(event);
+
+                x = (int) event.getRawX();
+                y = (int) event.getRawY();
+
+                mVelocityTracker.computeCurrentVelocity(1000);
+                fling(x, y, mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
+
+                mWindowManager.setSlippery(true);
+                releaseBackground();
+                break;
+        }
+        return true;
+    }
+
+    private void convertToScreenCoordinates(MotionEvent event) {
+        event.setLocation(event.getRawX(), event.getRawY());
+    }
+
+    private void fling(int x, int y, float xVelocity, float yVelocity) {
+        int position = calculatePosition(x, y);
+        float velocity = isHorizontalDivision() ? yVelocity : xVelocity;
+        final SnapTarget snapTarget = new DividerSnapAlgorithm(getContext(), mFlingAnimationUtils,
+                mDividerSize, isHorizontalDivision()).calculateSnapTarget(position, velocity);
+
+        ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
+        anim.addUpdateListener(new AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                resizeStack((Integer) animation.getAnimatedValue());
+            }
+        });
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                commitSnapFlags(snapTarget);
+                mWindowManagerProxy.setResizing(false);
+                mDockSide = WindowManager.DOCKED_INVALID;
+            }
+        });
+        mFlingAnimationUtils.apply(anim, position, snapTarget.position, velocity);
+        anim.start();
+    }
+
+    private void commitSnapFlags(SnapTarget target) {
+        if (target.flag == SnapTarget.FLAG_NONE) {
+            return;
+        }
+        boolean dismissOrMaximize;
+        if (target.flag == SnapTarget.FLAG_DISMISS_START) {
+            dismissOrMaximize = mDockSide == WindowManager.DOCKED_LEFT
+                    || mDockSide == WindowManager.DOCKED_TOP;
+        } else {
+            dismissOrMaximize = mDockSide == WindowManager.DOCKED_RIGHT
+                    || mDockSide == WindowManager.DOCKED_BOTTOM;
+        }
+        if (dismissOrMaximize) {
+            mWindowManagerProxy.dismissDockedStack();
+        } else {
+            mWindowManagerProxy.maximizeDockedStack();
+        }
+    }
+
+    private void liftBackground() {
+        if (isHorizontalDivision()) {
+            mBackground.animate().scaleY(1.5f);
+        } else {
+            mBackground.animate().scaleX(1.5f);
+        }
+        mBackground.animate()
+                .setInterpolator(mTouchResponseInterpolator)
+                .setDuration(150)
+                .translationZ(mTouchElevation);
+
+        // Lift handle as well so it doesn't get behind the background, even though it doesn't
+        // cast shadow.
+        mHandle.animate()
+                .setInterpolator(mTouchResponseInterpolator)
+                .setDuration(150)
+                .translationZ(mTouchElevation);
+    }
+
+    private void releaseBackground() {
+        mBackground.animate()
+                .setInterpolator(mFastOutSlowInInterpolator)
+                .setDuration(200)
+                .translationZ(0)
+                .scaleX(1f)
+                .scaleY(1f);
+        mHandle.animate()
+                .setInterpolator(mFastOutSlowInInterpolator)
+                .setDuration(200)
+                .translationZ(0);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateDisplayInfo();
+    }
+
+    private void updateDisplayInfo() {
+        final DisplayManager displayManager =
+                (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+        Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+        final DisplayInfo info = new DisplayInfo();
+        display.getDisplayInfo(info);
+        mDisplayWidth = info.logicalWidth;
+        mDisplayHeight = info.logicalHeight;
+    }
+
+    private int calculatePosition(int touchX, int touchY) {
+        return isHorizontalDivision() ? calculateYPosition(touchY) : calculateXPosition(touchX);
+    }
+
+    private boolean isHorizontalDivision() {
+        return mDockSide == WindowManager.DOCKED_TOP
+                || mDockSide == WindowManager.DOCKED_BOTTOM;
+    }
+
+    private int calculateXPosition(int touchX) {
+        return mStartPosition + touchX - mStartX;
+    }
+
+    private int calculateYPosition(int touchY) {
+        return mStartPosition + touchY - mStartY;
+    }
+
+    private void resizeStack(int position) {
+        mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+        switch (mDockSide) {
+            case WindowManager.DOCKED_LEFT:
+                mTmpRect.right = position;
+                break;
+            case WindowManager.DOCKED_TOP:
+                mTmpRect.bottom = position;
+                break;
+            case WindowManager.DOCKED_RIGHT:
+                mTmpRect.left = position + mDividerWindowWidth - 2 * mDividerInsets;
+                break;
+            case WindowManager.DOCKED_BOTTOM:
+                mTmpRect.top = position + mDividerWindowWidth - 2 * mDividerInsets;
+                break;
+        }
+        if (mTmpRect.equals(mLastResizeRect)) {
+            return;
+        }
+
+        // Make sure shadows are updated
+        mBackground.invalidate();
+
+        mLastResizeRect.set(mTmpRect);
+        mWindowManagerProxy.resizeDockedStack(mTmpRect);
+    }
+
+    @Override
+    public void onComputeInternalInsets(InternalInsetsInfo inoutInfo) {
+        inoutInfo.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+        inoutInfo.touchableRegion.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(),
+                mHandle.getBottom());
+        inoutInfo.touchableRegion.op(mBackground.getLeft(), mBackground.getTop(),
+                mBackground.getRight(), mBackground.getBottom(), Op.UNION);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
new file mode 100644
index 0000000..2251874
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.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.systemui.stackdivider;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.View;
+import android.view.WindowManager;
+
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+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.TYPE_DOCK_DIVIDER;
+
+/**
+ * Manages the window parameters of the docked stack divider.
+ */
+public class DividerWindowManager {
+
+    private static final String WINDOW_TITLE = "DockedStackDivider";
+
+    private final WindowManager mWindowManager;
+    private WindowManager.LayoutParams mLp;
+    private View mView;
+
+    public DividerWindowManager(Context ctx) {
+        mWindowManager = ctx.getSystemService(WindowManager.class);
+    }
+
+    public void add(View view, int width, int height) {
+        mLp = new WindowManager.LayoutParams(
+                width, height, TYPE_DOCK_DIVIDER,
+                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL
+                        | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY,
+                PixelFormat.TRANSLUCENT);
+        mLp.setTitle(WINDOW_TITLE);
+        mWindowManager.addView(view, mLp);
+        mView = view;
+    }
+
+    public void remove() {
+        if (mView != null) {
+            mWindowManager.removeView(mView);
+        }
+        mView = null;
+    }
+
+    public void setSlippery(boolean slippery) {
+        boolean changed = false;
+        if (slippery && (mLp.flags & FLAG_SLIPPERY) == 0) {
+            mLp.flags |= FLAG_SLIPPERY;
+            changed = true;
+        } else if (!slippery && (mLp.flags & FLAG_SLIPPERY) != 0) {
+            mLp.flags &= ~FLAG_SLIPPERY;
+            changed = true;
+        }
+        if (changed) {
+            mWindowManager.updateViewLayout(mView, mLp);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
new file mode 100644
index 0000000..0d3f803
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -0,0 +1,117 @@
+/*
+ * 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.stackdivider;
+
+import android.app.ActivityManagerNative;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.WindowManagerGlobal;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.view.WindowManager.DOCKED_INVALID;
+
+/**
+ * Proxy to simplify calls into window manager/activity manager
+ */
+public class WindowManagerProxy {
+
+    private static final String TAG = "WindowManagerProxy";
+
+    @GuardedBy("mResizeRect")
+    private final Rect mResizeRect = new Rect();
+    private final Rect mTmpRect = new Rect();
+    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+
+    private final Runnable mResizeRunnable = new Runnable() {
+        @Override
+        public void run() {
+            synchronized (mResizeRect) {
+                mTmpRect.set(mResizeRect);
+            }
+            try {
+                ActivityManagerNative.getDefault().resizeStack(DOCKED_STACK_ID, mTmpRect, true);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to resize stack: " + e);
+            }
+        }
+    };
+
+    private final Runnable mDismissRunnable = new Runnable() {
+        @Override
+        public void run() {
+            try {
+                ActivityManagerNative.getDefault().removeStack(DOCKED_STACK_ID);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to remove stack: " + e);
+            }
+        }
+    };
+
+    private final Runnable mMaximizeRunnable = new Runnable() {
+        @Override
+        public void run() {
+            try {
+                ActivityManagerNative.getDefault().resizeStack(DOCKED_STACK_ID, null, true);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to resize stack: " + e);
+            }
+        }
+    };
+
+    public void resizeDockedStack(Rect rect) {
+        synchronized (mResizeRect) {
+            mResizeRect.set(rect);
+        }
+        mExecutor.execute(mResizeRunnable);
+    }
+
+    public void dismissDockedStack() {
+        mExecutor.execute(mDismissRunnable);
+    }
+
+    public void maximizeDockedStack() {
+        mExecutor.execute(mMaximizeRunnable);
+    }
+
+    public void setResizing(final boolean resizing) {
+        mExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    WindowManagerGlobal.getWindowManagerService().setDockedStackResizing(resizing);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Error calling setDockedStackResizing: " + e);
+                }
+            }
+        });
+    }
+
+    public int getDockSide() {
+        try {
+            return WindowManagerGlobal.getWindowManagerService().getDockedStackSide();
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to get dock side: " + e);
+        }
+        return DOCKED_INVALID;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 3f0000e..069279f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -62,6 +62,7 @@
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -175,6 +176,7 @@
     protected boolean mDeviceInteractive;
 
     protected boolean mVisible;
+    protected ArraySet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new ArraySet<>();
 
     // mScreenOnFromKeyguard && mVisible.
     private boolean mVisibleToUser;
@@ -1664,7 +1666,10 @@
                 return;
             }
 
-            final PendingIntent intent = sbn.getNotification().contentIntent;
+            Notification notification = sbn.getNotification();
+            final PendingIntent intent = notification.contentIntent != null
+                    ? notification.contentIntent
+                    : notification.fullScreenIntent;
             final String notificationKey = sbn.getKey();
 
             // Mark notification for one frame.
@@ -1746,8 +1751,8 @@
         }
 
         public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
-            final PendingIntent contentIntent = sbn.getNotification().contentIntent;
-            if (contentIntent != null) {
+            Notification notification = sbn.getNotification();
+            if (notification.contentIntent != null || notification.fullScreenIntent != null) {
                 row.setOnClickListener(this);
             } else {
                 row.setOnClickListener(null);
@@ -2013,6 +2018,8 @@
         Entry entry = mNotificationData.get(key);
         if (entry == null) {
             return;
+        } else if (mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
+            mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
         }
 
         Notification n = notification.getNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
index a51f62a..58c9722 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
@@ -1060,7 +1060,7 @@
             ris = packageManager.queryIntentActivitiesAsUser(intentToResolve, 0, userId);
         }
         if (ris == null || ris.size() <= 0) {
-            Slog.e(TAG, "Failed to build intent for " + packageName);
+            Slog.i(TAG, "Failed to build intent for " + packageName);
             return null;
         }
         return new ComponentName(ris.get(0).activityInfo.packageName,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
index d527f29..76a9798 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
@@ -179,7 +179,7 @@
             }
         }
 
-        Slog.e(TAG, "Activity doesn't have category Intent.CATEGORY_LAUNCHER " + component);
+        Slog.i(TAG, "Activity doesn't have category Intent.CATEGORY_LAUNCHER " + component);
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index bbef1c0..fbe9730 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -84,10 +84,10 @@
             // the close future. See b/23676310 for reference.
             return;
         }
-        if (notif.isGroupSummary()) {
-            group.summary = null;
-        } else {
+        if (notif.isGroupChild()) {
             group.children.remove(removed);
+        } else {
+            group.summary = null;
         }
         if (group.children.isEmpty()) {
             if (group.summary == null) {
@@ -107,17 +107,17 @@
             group = new NotificationGroup();
             mGroupMap.put(groupKey, group);
         }
-        if (notif.isGroupSummary()) {
+        if (notif.isGroupChild()) {
+            group.children.add(added);
+            if (group.summary != null && group.children.size() == 1 && !group.expanded) {
+                group.summary.row.updateNotificationHeader();
+            }
+        } else {
             group.summary = added;
             group.expanded = added.row.areChildrenExpanded();
             if (!group.children.isEmpty()) {
                 mListener.onGroupCreatedFromChildren(group);
             }
-        } else {
-            group.children.add(added);
-            if (group.summary != null && group.children.size() == 1 && !group.expanded) {
-                group.summary.row.updateNotificationHeader();
-            }
         }
     }
 
@@ -169,7 +169,7 @@
      * @return whether a given notification is a summary in a group which has children
      */
     public boolean isSummaryOfGroup(StatusBarNotification sbn) {
-        if (sbn.getNotification().isGroupChild()) {
+        if (!sbn.getNotification().isGroupSummary()) {
             return false;
         }
         NotificationGroup group = mGroupMap.get(sbn.getGroupKey());
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 3e52515..9ab2a2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -617,7 +617,6 @@
     };
     private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
             = new HashMap<>();
-    private HashSet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new HashSet<>();
     private RankingMap mLatestRankingMap;
     private boolean mNoAnimationOnNextBarModeChange;
     private FalsingManager mFalsingManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
index 18db5b8..512af1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
@@ -19,16 +19,13 @@
 import android.animation.Animator.AnimatorListener;
 import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.graphics.drawable.RippleDrawable;
-import android.os.Handler;
-import android.os.Message;
 import android.util.AttributeSet;
+import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
-
 import com.android.keyguard.AlphaOptimizedImageButton;
 
 public class SettingsButton extends AlphaOptimizedImageButton {
@@ -157,6 +154,7 @@
 
     protected void startContinuousSpin() {
         cancelAnimation();
+        performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
         mUpToSpeed = true;
         mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360);
         mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index dc9f5e8..5cfd174 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -458,7 +458,10 @@
             mReleaseOnExpandFinish = false;
         } else {
             for (NotificationData.Entry entry : mEntriesToRemoveAfterExpand) {
-                removeHeadsUpEntry(entry);
+                if (isHeadsUp(entry.key)) {
+                    // Maybe the heads-up was removed already
+                    removeHeadsUpEntry(entry);
+                }
             }
         }
         mEntriesToRemoveAfterExpand.clear();
@@ -596,6 +599,9 @@
                 postTime = Math.max(postTime, currentTime);
             }
             removeAutoRemovalCallbacks();
+            if (mEntriesToRemoveAfterExpand.contains(entry)) {
+                mEntriesToRemoveAfterExpand.remove(entry);
+            }
             if (!hasFullScreenIntent(entry) && !mRemoteInputActive) {
                 long finishTime = postTime + mHeadsUpNotificationDecay;
                 long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 911d6a2..dc7c967 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -16,9 +16,10 @@
 package com.android.systemui.tuner;
 
 import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
 import android.app.FragmentTransaction;
 import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
@@ -33,7 +34,6 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
@@ -51,6 +51,8 @@
 
     public static final String SETTING_SEEN_TUNER_WARNING = "seen_tuner_warning";
 
+    private static final String WARNING_TAG = "tuner_warning";
+
     private static final int MENU_REMOVE = Menu.FIRST + 1;
 
     private final SettingObserver mSettingObserver = new SettingObserver();
@@ -90,16 +92,9 @@
         mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT);
         if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING,
                 0) == 0) {
-            new AlertDialog.Builder(getContext())
-                    .setTitle(R.string.tuner_warning_title)
-                    .setMessage(R.string.tuner_warning)
-                    .setPositiveButton(R.string.got_it, new OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            Settings.Secure.putInt(getContext().getContentResolver(),
-                                    SETTING_SEEN_TUNER_WARNING, 1);
-                        }
-                    }).show();
+            if (getFragmentManager().findFragmentByTag(WARNING_TAG) == null) {
+                new TunerWarningFragment().show(getFragmentManager(), WARNING_TAG);
+            }
         }
         TunerService.get(getContext()).addTunable(mQsPaging, QSPanel.QS_THE_NEW_QS);
     }
@@ -187,4 +182,20 @@
             mQsTuner.setEnabled(newValue == null || Integer.parseInt(newValue) == 0);
         }
     };
+
+    public static class TunerWarningFragment extends DialogFragment {
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            return new AlertDialog.Builder(getContext())
+                    .setTitle(R.string.tuner_warning_title)
+                    .setMessage(R.string.tuner_warning)
+                    .setPositiveButton(R.string.got_it, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            Settings.Secure.putInt(getContext().getContentResolver(),
+                                    SETTING_SEEN_TUNER_WARNING, 1);
+                        }
+                    }).show();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index 71559389..1e3b0f1 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -116,8 +116,12 @@
 
     public void reloadSetting(Uri uri) {
         String key = mListeningUris.get(uri);
+        List<Tunable> tunables = mTunableLookup.get(key);
+        if (tunables == null) {
+            return;
+        }
         String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser);
-        for (Tunable tunable : mTunableLookup.get(key)) {
+        for (Tunable tunable : tunables) {
             tunable.onTuningChanged(key, value);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 1770a06..cd47ac1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -70,9 +70,7 @@
     private static final int SECONDS_MS = 1000;
     private static final int MINUTES_MS = 60 * SECONDS_MS;
 
-    private static final int[] MINUTE_BUCKETS = DEBUG
-            ? new int[] { 0, 1, 2, 5, 15, 30, 45, 60, 120, 180, 240, 480 }
-            : ZenModeConfig.MINUTE_BUCKETS;
+    private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
     private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
     private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
     private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
@@ -604,13 +602,6 @@
         if (DEBUG) Log.d(mTag, "bind i=" + mZenConditions.indexOfChild(row) + " first=" + first
                 + " condition=" + conditionId);
         tag.rb.setEnabled(enabled);
-        final boolean checked = (mSessionExitCondition != null
-                    || mAttachedZen != Global.ZEN_MODE_OFF)
-                && (sameConditionId(mSessionExitCondition, tag.condition));
-        if (checked != tag.rb.isChecked()) {
-            if (DEBUG) Log.d(mTag, "bind checked=" + checked + " condition=" + conditionId);
-            tag.rb.setChecked(checked);
-        }
         tag.rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
diff --git a/packages/VpnDialogs/res/values-ro/strings.xml b/packages/VpnDialogs/res/values-ro/strings.xml
index f7a6a6a..a77ef03 100644
--- a/packages/VpnDialogs/res/values-ro/strings.xml
+++ b/packages/VpnDialogs/res/values-ro/strings.xml
@@ -19,7 +19,7 @@
     <string name="prompt" msgid="3183836924226407828">"Solicitare de conexiune"</string>
     <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> dorește să configureze o conexiune VPN care să îi permită să monitorizeze traficul în rețea. Acceptați numai dacă aveți încredere în sursă. Atunci când conexiunea VPN este activă, &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; se afișează în partea de sus a ecranului."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN este conectat"</string>
-    <string name="configure" msgid="4905518375574791375">"Configuraţi"</string>
+    <string name="configure" msgid="4905518375574791375">"Configurați"</string>
     <string name="disconnect" msgid="971412338304200056">"Deconectaţi"</string>
     <string name="session" msgid="6470628549473641030">"Sesiune:"</string>
     <string name="duration" msgid="3584782459928719435">"Durată:"</string>
diff --git a/packages/services/Proxy/AndroidManifest.xml b/packages/services/Proxy/AndroidManifest.xml
index bbcd6b9..88f8381 100644
--- a/packages/services/Proxy/AndroidManifest.xml
+++ b/packages/services/Proxy/AndroidManifest.xml
@@ -7,7 +7,9 @@
 
     <application
         android:label="@string/app_label"
-        android:process="com.android.proxyhandler">
+        android:process="com.android.proxyhandler"
+        android:forceDeviceEncrypted="true"
+        android:encryptionAware="true">
 
         <service android:name=".ProxyService"
             android:exported="true">
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index 54180f4..9bbacbc 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -278,6 +278,8 @@
             public ValueAndSize(RenderScript rs, Object obj) {
                 if (obj instanceof Allocation) {
                     value = ((Allocation)obj).getID(rs);
+                    // Special value for size to tell the runtime and driver that
+                    // the value is an Allocation
                     size = -1;
                 } else if (obj instanceof Boolean) {
                     value = ((Boolean)obj).booleanValue() ? 1 : 0;
@@ -289,10 +291,10 @@
                     value = ((Long)obj).longValue();
                     size = 8;
                 } else if (obj instanceof Float) {
-                    value = ((Float)obj).longValue();
+                    value = Float.floatToRawIntBits(((Float)obj).floatValue());
                     size = 4;
                 } else if (obj instanceof Double) {
-                    value = ((Double)obj).longValue();
+                    value = Double.doubleToRawLongBits(((Double)obj).doubleValue());
                     size = 8;
                 }
             }
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index be7071e..113241d 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -393,7 +393,6 @@
 
   size_t numValues, numDependencies;
   RsScriptFieldID* fieldIDs;
-  uintptr_t* values;
   RsClosure* depClosures;
   RsScriptFieldID* depFieldIDs;
 
@@ -430,15 +429,6 @@
     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
   }
 
-  values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues);
-  if (values == nullptr) {
-      goto exit;
-  }
-
-  for (size_t i = 0; i < numValues; i++) {
-    values[i] = (uintptr_t)jValues[i];
-  }
-
   depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies);
   if (depClosures == nullptr) {
       goto exit;
@@ -459,7 +449,7 @@
 
   ret = (jlong)(uintptr_t)rsClosureCreate(
       (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
-      fieldIDs, numValues, values, numValues,
+      fieldIDs, numValues, jValues, numValues,
       (int*)jSizes, numValues,
       depClosures, numDependencies,
       depFieldIDs, numDependencies);
@@ -511,7 +501,6 @@
 
   size_t numValues;
   RsScriptFieldID* fieldIDs;
-  uintptr_t* values;
 
   if (fieldIDs_length != values_length || values_length != sizes_length) {
       ALOGE("Unmatched field IDs, values, and sizes in closure creation.");
@@ -534,18 +523,9 @@
     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
   }
 
-  values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues);
-  if (values == nullptr) {
-      goto exit;
-  }
-
-  for (size_t i = 0; i < numValues; i++) {
-    values[i] = (uintptr_t)jValues[i];
-  }
-
   ret = (jlong)(uintptr_t)rsInvokeClosureCreate(
       (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
-      fieldIDs, numValues, values, numValues,
+      fieldIDs, numValues, jValues, numValues,
       (int*)jSizes, numValues);
 
 exit:
@@ -561,15 +541,17 @@
 static void
 nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
                jint index, jlong value, jint size) {
+  // Size is signed with -1 indicating the value is an Allocation
   rsClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
-                  (uintptr_t)value, (size_t)size);
+                  (uintptr_t)value, size);
 }
 
 static void
 nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
                   jlong fieldID, jlong value, jint size) {
+  // Size is signed with -1 indicating the value is an Allocation
   rsClosureSetGlobal((RsContext)con, (RsClosure)closureID,
-                     (RsScriptFieldID)fieldID, (uintptr_t)value, (size_t)size);
+                     (RsScriptFieldID)fieldID, (int64_t)value, size);
 }
 
 static long
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index b4411cf..781d134 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -341,7 +341,7 @@
         mTransformationAnimator.start();
     }
 
-    private void setMagnificationSpec(MagnificationSpec spec) {
+    public void setMagnificationSpec(MagnificationSpec spec) {
         if (DEBUG_SET_MAGNIFICATION_SPEC) {
             Slog.i(LOG_TAG, "Sending: " + spec);
         }
@@ -351,6 +351,10 @@
         mWindowManager.setMagnificationSpec(MagnificationSpec.obtain(spec));
     }
 
+    public MagnificationSpec getMagnificationSpec() {
+        return mSentMagnificationSpec;
+    }
+
     private static class MagnificationSpecEvaluator implements TypeEvaluator<MagnificationSpec> {
         private final MagnificationSpec mTempTransformationSpec = MagnificationSpec.obtain();
 
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 02b5b8a..25fef18 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -79,10 +79,11 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
-
 import com.android.server.LocalServices;
 import com.android.server.WidgetBackupProvider;
+
 import libcore.io.IoUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -1954,8 +1955,13 @@
                 if (period < MIN_UPDATE_PERIOD) {
                     period = MIN_UPDATE_PERIOD;
                 }
-                mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                        SystemClock.elapsedRealtime() + period, period, provider.broadcast);
+                final long oldId = Binder.clearCallingIdentity();
+                try {
+                    mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                            SystemClock.elapsedRealtime() + period, period, provider.broadcast);
+                } finally {
+                    Binder.restoreCallingIdentity(oldId);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a5ddc12..f9d9950 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -115,6 +115,7 @@
     final LocalLog mLog = new LocalLog(TAG);
 
     AppOpsManager mAppOps;
+    DeviceIdleController.LocalService mLocalDeviceIdleController;
 
     final Object mLock = new Object();
 
@@ -897,6 +898,8 @@
         if (phase == PHASE_SYSTEM_SERVICES_READY) {
             mConstants.start(getContext().getContentResolver());
             mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
+            mLocalDeviceIdleController
+                    = LocalServices.getService(DeviceIdleController.LocalService.class);
         }
     }
 
@@ -2468,10 +2471,9 @@
 
     private class AlarmHandler extends Handler {
         public static final int ALARM_EVENT = 1;
-        public static final int MINUTE_CHANGE_EVENT = 2;
-        public static final int DATE_CHANGE_EVENT = 3;
-        public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 4;
-        public static final int LISTENER_TIMEOUT = 5;
+        public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 2;
+        public static final int LISTENER_TIMEOUT = 3;
+        public static final int REPORT_ALARMS_ACTIVE = 4;
         
         public AlarmHandler() {
         }
@@ -2511,6 +2513,12 @@
                     mDeliveryTracker.alarmTimedOut((IBinder) msg.obj);
                     break;
 
+                case REPORT_ALARMS_ACTIVE:
+                    if (mLocalDeviceIdleController != null) {
+                        mLocalDeviceIdleController.setAlarmsActive(msg.arg1 != 0);
+                    }
+                    break;
+
                 default:
                     // nope, just ignore it
                     break;
@@ -2740,6 +2748,7 @@
             }
             mBroadcastRefCount--;
             if (mBroadcastRefCount == 0) {
+                mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0).sendToTarget();
                 mWakeLock.release();
                 if (mInFlight.size() > 0) {
                     mLog.w("Finished all dispatches with " + mInFlight.size()
@@ -2873,6 +2882,7 @@
                         alarm.type, alarm.statsTag, (alarm.operation == null) ? alarm.uid : -1,
                         true);
                 mWakeLock.acquire();
+                mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1).sendToTarget();
             }
             final InFlight inflight = new InFlight(AlarmManagerService.this,
                     alarm.operation, alarm.listener, alarm.workSource, alarm.uid,
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index fd67b41..f329cff 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -95,8 +95,6 @@
     private static final int MESSAGE_BLUETOOTH_STATE_CHANGE=60;
     private static final int MESSAGE_TIMEOUT_BIND =100;
     private static final int MESSAGE_TIMEOUT_UNBIND =101;
-    private static final int MESSAGE_GET_NAME_AND_ADDRESS=200;
-    private static final int MESSAGE_SAVE_NAME_AND_ADDRESS=201;
     private static final int MESSAGE_USER_SWITCHED = 300;
     private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
     private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
@@ -587,15 +585,6 @@
         }
     }
 
-    /** @hide*/
-    public void getNameAndAddress() {
-        if (DBG) {
-            Log.d(TAG,"getNameAndAddress(): mBluetooth = " + mBluetooth +
-                  " mBinding = " + mBinding);
-        }
-        Message msg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
-        mHandler.sendMessage(msg);
-    }
     public boolean enableNoAutoConnect()
     {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -681,14 +670,13 @@
             if (mUnbinding) return;
             mUnbinding = true;
             if (mBluetooth != null) {
-                if (!mConnection.isGetNameAddressOnly()) {
-                    //Unregister callback object
-                    try {
-                        mBluetooth.unregisterCallback(mBluetoothCallback);
-                    } catch (RemoteException re) {
-                        Log.e(TAG, "Unable to unregister BluetoothCallback",re);
-                    }
+                //Unregister callback object
+                try {
+                    mBluetooth.unregisterCallback(mBluetoothCallback);
+                } catch (RemoteException re) {
+                    Log.e(TAG, "Unable to unregister BluetoothCallback",re);
                 }
+
                 if (DBG) Log.d(TAG, "Sending unbind request.");
                 mBluetooth = null;
                 //Unbind
@@ -780,11 +768,6 @@
             if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");
             sendEnableMsg(mQuietEnableExternal);
         }
-        if (!isNameAndAddressSet()) {
-            // Sync the Bluetooth name and address from the Bluetooth Adapter
-            if (DBG) Log.d(TAG, "Retrieving Bluetooth Adapter name and address...");
-            getNameAndAddress();
-        }
     }
 
     /**
@@ -957,42 +940,38 @@
      * Inform BluetoothAdapter instances that Adapter service is up
      */
     private void sendBluetoothServiceUpCallback() {
-        if (!mConnection.isGetNameAddressOnly()) {
-            if (DBG) Log.d(TAG,"Calling onBluetoothServiceUp callbacks");
-            try {
-                int n = mCallbacks.beginBroadcast();
-                Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
-                for (int i=0; i <n;i++) {
-                    try {
-                        mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
-                    }  catch (RemoteException e) {
-                        Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
-                    }
+        if (DBG) Log.d(TAG,"Calling onBluetoothServiceUp callbacks");
+        try {
+            int n = mCallbacks.beginBroadcast();
+            Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
+            for (int i=0; i <n;i++) {
+                try {
+                    mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
+                }  catch (RemoteException e) {
+                    Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
                 }
-            } finally {
-                mCallbacks.finishBroadcast();
             }
+        } finally {
+            mCallbacks.finishBroadcast();
         }
     }
     /**
      * Inform BluetoothAdapter instances that Adapter service is down
      */
     private void sendBluetoothServiceDownCallback() {
-        if (!mConnection.isGetNameAddressOnly()) {
-            if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks");
-            try {
-                int n = mCallbacks.beginBroadcast();
-                Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
-                for (int i=0; i <n;i++) {
-                    try {
-                        mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
-                    }  catch (RemoteException e) {
-                        Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
-                    }
+        if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks");
+        try {
+            int n = mCallbacks.beginBroadcast();
+            Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
+            for (int i=0; i <n;i++) {
+                try {
+                    mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
+                }  catch (RemoteException e) {
+                    Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
                 }
-            } finally {
-                mCallbacks.finishBroadcast();
             }
+        } finally {
+            mCallbacks.finishBroadcast();
         }
     }
 
@@ -1052,17 +1031,6 @@
     }
 
     private class BluetoothServiceConnection implements ServiceConnection {
-
-        private boolean mGetNameAddressOnly;
-
-        public void setGetNameAddressOnly(boolean getOnly) {
-            mGetNameAddressOnly = getOnly;
-        }
-
-        public boolean isGetNameAddressOnly() {
-            return mGetNameAddressOnly;
-        }
-
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "BluetoothServiceConnection: " + className.getClassName());
             Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
@@ -1108,104 +1076,6 @@
         public void handleMessage(Message msg) {
             if (DBG) Log.d (TAG, "Message: " + msg.what);
             switch (msg.what) {
-                case MESSAGE_GET_NAME_AND_ADDRESS: {
-                    if (DBG) Log.d(TAG,"MESSAGE_GET_NAME_AND_ADDRESS");
-                    synchronized(mConnection) {
-                        //Start bind request
-                        if ((mBluetooth == null) && (!mBinding)) {
-                            if (DBG) Log.d(TAG, "Binding to service to get name and address");
-                            mConnection.setGetNameAddressOnly(true);
-                            //Start bind timeout and bind
-                            Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
-                            mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
-                            Intent i = new Intent(IBluetooth.class.getName());
-                            if (!doBind(i, mConnection,
-                                    Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
-                                    UserHandle.CURRENT)) {
-                                mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
-                            } else {
-                                mBinding = true;
-                            }
-                        }
-                        else {
-                            Message saveMsg= mHandler.obtainMessage(MESSAGE_SAVE_NAME_AND_ADDRESS);
-                            saveMsg.arg1 = 0;
-                            if (mBluetooth != null) {
-                                mHandler.sendMessage(saveMsg);
-                            } else {
-                                // if enable is also called to bind the service
-                                // wait for MESSAGE_BLUETOOTH_SERVICE_CONNECTED
-                                mHandler.sendMessageDelayed(saveMsg, TIMEOUT_SAVE_MS);
-                            }
-                        }
-                    }
-                    break;
-                }
-                case MESSAGE_SAVE_NAME_AND_ADDRESS: {
-                    boolean unbind = false;
-                    if (DBG) Log.d(TAG,"MESSAGE_SAVE_NAME_AND_ADDRESS");
-                    synchronized(mConnection) {
-                        if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
-                            try {
-                                mBluetooth.enable();
-                            } catch (RemoteException e) {
-                                Log.e(TAG,"Unable to call enable()",e);
-                            }
-                        }
-                    }
-                    if (mBluetooth != null && !mConnection.isGetNameAddressOnly()) waitForOnOff(true, false);
-                    synchronized(mConnection) {
-                        if (mBluetooth != null) {
-                            String name =  null;
-                            String address = null;
-                            try {
-                                name =  mBluetooth.getName();
-                                address = mBluetooth.getAddress();
-                            } catch (RemoteException re) {
-                                Log.e(TAG,"",re);
-                            }
-
-                            if (name != null && address != null) {
-                                storeNameAndAddress(name,address);
-                                if (mConnection.isGetNameAddressOnly()) {
-                                    unbind = true;
-                                }
-                            } else {
-                                if (msg.arg1 < MAX_SAVE_RETRIES) {
-                                    Message retryMsg = mHandler.obtainMessage(MESSAGE_SAVE_NAME_AND_ADDRESS);
-                                    retryMsg.arg1= 1+msg.arg1;
-                                    if (DBG) Log.d(TAG,"Retrying name/address remote retrieval and save.....Retry count =" + retryMsg.arg1);
-                                    mHandler.sendMessageDelayed(retryMsg, TIMEOUT_SAVE_MS);
-                                } else {
-                                    Log.w(TAG,"Maximum name/address remote retrieval retry exceeded");
-                                    if (mConnection.isGetNameAddressOnly()) {
-                                        unbind = true;
-                                    }
-                                }
-                            }
-                            if (!mEnable && !mConnection.isGetNameAddressOnly()) {
-                                try {
-                                    mBluetooth.disable();
-                                } catch (RemoteException e) {
-                                    Log.e(TAG,"Unable to call disable()",e);
-                                }
-                            }
-                        } else {
-                            // rebind service by Request GET NAME AND ADDRESS
-                            // if service is unbinded by disable or
-                            // MESSAGE_BLUETOOTH_SERVICE_CONNECTED is not received
-                            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
-                            mHandler.sendMessage(getMsg);
-                        }
-                    }
-                    if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
-                        waitForOnOff(false, true);
-                    }
-                    if (unbind) {
-                        unbindAndFinish();
-                    }
-                    break;
-                }
                 case MESSAGE_ENABLE:
                     if (DBG) {
                         Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);
@@ -1308,14 +1178,6 @@
                             Log.e(TAG,"Unable to call configHciSnoopLog", e);
                         }
 
-                        if (mConnection.isGetNameAddressOnly()) {
-                            //Request GET NAME AND ADDRESS
-                            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
-                            mHandler.sendMessage(getMsg);
-                            if (!mEnable) return;
-                        }
-
-                        mConnection.setGetNameAddressOnly(false);
                         //Register callback object
                         try {
                             mBluetooth.registerCallback(mBluetoothCallback);
@@ -1412,25 +1274,23 @@
                             SERVICE_RESTART_TIME_MS);
                     }
 
-                    if (!mConnection.isGetNameAddressOnly()) {
-                        sendBluetoothServiceDownCallback();
+                    sendBluetoothServiceDownCallback();
 
-                        // Send BT state broadcast to update
-                        // the BT icon correctly
-                        if ((mState == BluetoothAdapter.STATE_TURNING_ON) ||
-                            (mState == BluetoothAdapter.STATE_ON)) {
-                            bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
-                                                        BluetoothAdapter.STATE_TURNING_OFF);
-                            mState = BluetoothAdapter.STATE_TURNING_OFF;
-                        }
-                        if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
-                            bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
-                                                        BluetoothAdapter.STATE_OFF);
-                        }
-
-                        mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
-                        mState = BluetoothAdapter.STATE_OFF;
+                    // Send BT state broadcast to update
+                    // the BT icon correctly
+                    if ((mState == BluetoothAdapter.STATE_TURNING_ON) ||
+                        (mState == BluetoothAdapter.STATE_ON)) {
+                        bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
+                                                    BluetoothAdapter.STATE_TURNING_OFF);
+                        mState = BluetoothAdapter.STATE_TURNING_OFF;
                     }
+                    if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
+                        bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
+                                                    BluetoothAdapter.STATE_OFF);
+                    }
+
+                    mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
+                    mState = BluetoothAdapter.STATE_OFF;
                     break;
                 }
                 case MESSAGE_RESTART_BLUETOOTH_SERVICE:
@@ -1539,7 +1399,6 @@
                 //Start bind timeout and bind
                 Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
                 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
-                mConnection.setGetNameAddressOnly(false);
                 Intent i = new Intent(IBluetooth.class.getName());
                 if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                         UserHandle.CURRENT)) {
@@ -1548,21 +1407,6 @@
                     mBinding = true;
                 }
             } else if (mBluetooth != null) {
-                if (mConnection.isGetNameAddressOnly()) {
-                    // if GetNameAddressOnly is set, we can clear this flag,
-                    // so the service won't be unbind
-                    // after name and address are saved
-                    mConnection.setGetNameAddressOnly(false);
-                    //Register callback object
-                    try {
-                        mBluetooth.registerCallback(mBluetoothCallback);
-                    } catch (RemoteException re) {
-                        Log.e(TAG, "Unable to register BluetoothCallback",re);
-                    }
-                    //Inform BluetoothAdapter instances that service is up
-                    sendBluetoothServiceUpCallback();
-                }
-
                 //Enable bluetooth
                 try {
                     if (!mQuietEnable) {
@@ -1594,9 +1438,7 @@
 
     private void handleDisable() {
         synchronized(mConnection) {
-            // don't need to disable if GetNameAddressOnly is set,
-            // service will be unbinded after Name and Address are saved
-            if ((mBluetooth != null) && (!mConnection.isGetNameAddressOnly())) {
+            if (mBluetooth != null) {
                 if (DBG) Log.d(TAG,"Sending off request.");
 
                 try {
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
index 73e8c52..019d03d 100644
--- a/services/core/java/com/android/server/BluetoothService.java
+++ b/services/core/java/com/android/server/BluetoothService.java
@@ -31,14 +31,15 @@
 
     @Override
     public void onStart() {
-        Log.d(TAG, "onStart: publishing BluetoothManagerService");
-        publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService);
     }
 
     @Override
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
+            publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService);
+        } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+            Log.d(TAG, "onBootPhase: PHASE_ACTIVITY_MANAGER_READY");
             mBluetoothManagerService.handleOnBootPhase();
         }
     }
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 927b995..485e26b 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -48,6 +48,7 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.IDeviceIdleController;
 import android.os.Looper;
 import android.os.Message;
@@ -196,6 +197,12 @@
     private long mNextIdleDelay;
     private long mNextLightAlarmTime;
 
+    private int mActiveIdleOpCount;
+    private IBinder mDownloadServiceActive;
+    private boolean mSyncActive;
+    private boolean mJobsActive;
+    private boolean mAlarmsActive;
+
     public final AtomicFile mConfigFile;
 
     /**
@@ -282,16 +289,22 @@
                 }
             } else if (ACTION_STEP_LIGHT_IDLE_STATE.equals(intent.getAction())) {
                 synchronized (DeviceIdleController.this) {
-                    stepLightIdleStateLocked();
+                    stepLightIdleStateLocked("s:alarm");
                 }
             } else if (ACTION_STEP_IDLE_STATE.equals(intent.getAction())) {
                 synchronized (DeviceIdleController.this) {
-                    stepIdleStateLocked();
+                    stepIdleStateLocked("s:alarm");
                 }
             }
         }
     };
 
+    private final BroadcastReceiver mIdleStartedDoneReceiver = new BroadcastReceiver() {
+        @Override public void onReceive(Context context, Intent intent) {
+            decActiveIdleOps();
+        }
+    };
+
     private final DisplayManager.DisplayListener mDisplayListener
             = new DisplayManager.DisplayListener() {
         @Override public void onDisplayAdded(int displayId) {
@@ -733,7 +746,7 @@
                 // If we are currently sensing, it is time to move to locating.
                 synchronized (this) {
                     mNotMoving = true;
-                    stepIdleStateLocked();
+                    stepIdleStateLocked("s:stationary");
                 }
             } else if (mState == STATE_LOCATING) {
                 // If we are currently locating, note that we are not moving and step
@@ -741,7 +754,7 @@
                 synchronized (this) {
                     mNotMoving = true;
                     if (mLocated) {
-                        stepIdleStateLocked();
+                        stepIdleStateLocked("s:stationary");
                     }
                 }
             }
@@ -804,11 +817,18 @@
                     } catch (RemoteException e) {
                     }
                     if (fullChanged) {
-                        getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
+                        incActiveIdleOps();
+                        getContext().sendOrderedBroadcastAsUser(mIdleIntent, UserHandle.ALL,
+                                null, mIdleStartedDoneReceiver, null, 0, null, null);
                     }
                     if (lightChanged) {
-                        getContext().sendBroadcastAsUser(mLightIdleIntent, UserHandle.ALL);
+                        incActiveIdleOps();
+                        getContext().sendOrderedBroadcastAsUser(mLightIdleIntent, UserHandle.ALL,
+                                null, mIdleStartedDoneReceiver, null, 0, null, null);
                     }
+                    // Always start with one active op for the message being sent here.
+                    // Now we we done!
+                    decActiveIdleOps();
                     EventLogTags.writeDeviceIdleOffComplete();
                 } break;
                 case MSG_REPORT_ACTIVE: {
@@ -913,11 +933,23 @@
         }
 
         @Override public void exitIdle(String reason) {
-            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+            getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
                     null);
             exitIdleInternal(reason);
         }
 
+        @Override public void downloadServiceActive(IBinder token) {
+            getContext().enforceCallingOrSelfPermission(
+                    "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
+            DeviceIdleController.this.downloadServiceActive(token);
+        }
+
+        @Override public void downloadServiceInactive() {
+            getContext().enforceCallingOrSelfPermission(
+                    "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
+            DeviceIdleController.this.downloadServiceInactive();
+        }
+
         @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             DeviceIdleController.this.dump(fd, pw, args);
         }
@@ -937,6 +969,19 @@
         public void setNetworkPolicyTempWhitelistCallback(Runnable callback) {
             setNetworkPolicyTempWhitelistCallbackInternal(callback);
         }
+
+        public void setSyncActive(boolean active) {
+            DeviceIdleController.this.setSyncActive(active);
+        }
+
+        public void setJobsActive(boolean active) {
+            DeviceIdleController.this.setJobsActive(active);
+        }
+
+        // Up-call from alarm manager.
+        public void setAlarmsActive(boolean active) {
+            DeviceIdleController.this.setAlarmsActive(active);
+        }
     }
 
     public DeviceIdleController(Context context) {
@@ -1439,7 +1484,7 @@
         }
     }
 
-    void stepLightIdleStateLocked() {
+    void stepLightIdleStateLocked(String reason) {
         if (mLightState == LIGHT_STATE_OVERRIDE) {
             // If we are already in full device idle mode, then
             // there is nothing left to do for light mode.
@@ -1455,22 +1500,23 @@
                 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_TIMEOUT);
                 if (DEBUG) Slog.d(TAG, "Moved to LIGHT_STATE_IDLE.");
                 mLightState = LIGHT_STATE_IDLE;
-                EventLogTags.writeDeviceIdleLight(mLightState, "step");
+                EventLogTags.writeDeviceIdleLight(mLightState, reason);
                 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON_LIGHT);
                 break;
             case LIGHT_STATE_IDLE:
                 // We have been idling long enough, now it is time to do some work.
+                mActiveIdleOpCount = 1;
                 scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_PENDING_TIMEOUT);
                 if (DEBUG) Slog.d(TAG,
                         "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
                 mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
-                EventLogTags.writeDeviceIdleLight(mLightState, "step");
+                EventLogTags.writeDeviceIdleLight(mLightState, reason);
                 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
                 break;
         }
     }
 
-    void stepIdleStateLocked() {
+    void stepIdleStateLocked(String reason) {
         if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
         EventLogTags.writeDeviceIdleStep();
 
@@ -1494,12 +1540,12 @@
                 mNextIdleDelay = mConstants.IDLE_TIMEOUT;
                 mState = STATE_IDLE_PENDING;
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
-                EventLogTags.writeDeviceIdle(mState, "step");
+                EventLogTags.writeDeviceIdle(mState, reason);
                 break;
             case STATE_IDLE_PENDING:
                 mState = STATE_SENSING;
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
-                EventLogTags.writeDeviceIdle(mState, "step");
+                EventLogTags.writeDeviceIdle(mState, reason);
                 scheduleAlarmLocked(mConstants.SENSING_TIMEOUT, false);
                 cancelLocatingLocked();
                 mAnyMotionDetector.checkForAnyMotion();
@@ -1511,7 +1557,7 @@
             case STATE_SENSING:
                 mState = STATE_LOCATING;
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
-                EventLogTags.writeDeviceIdle(mState, "step");
+                EventLogTags.writeDeviceIdle(mState, reason);
                 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
                 if (mLocationManager != null
                         && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
@@ -1553,23 +1599,101 @@
                     mLightState = LIGHT_STATE_OVERRIDE;
                     cancelLightAlarmLocked();
                 }
-                EventLogTags.writeDeviceIdle(mState, "step");
+                EventLogTags.writeDeviceIdle(mState, reason);
                 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
                 break;
             case STATE_IDLE:
                 // We have been idling long enough, now it is time to do some work.
+                mActiveIdleOpCount = 1;
                 scheduleAlarmLocked(mNextIdlePendingDelay, false);
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
                         "Next alarm in " + mNextIdlePendingDelay + " ms.");
                 mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
                         (long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
                 mState = STATE_IDLE_MAINTENANCE;
-                EventLogTags.writeDeviceIdle(mState, "step");
+                EventLogTags.writeDeviceIdle(mState, reason);
                 mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
                 break;
         }
     }
 
+    void incActiveIdleOps() {
+        synchronized (this) {
+            mActiveIdleOpCount++;
+        }
+    }
+
+    void decActiveIdleOps() {
+        synchronized (this) {
+            mActiveIdleOpCount--;
+            if (mActiveIdleOpCount <= 0) {
+                exitMaintenanceEarlyIfNeededLocked();
+            }
+        }
+    }
+
+    void downloadServiceActive(IBinder token) {
+        synchronized (this) {
+            mDownloadServiceActive = token;
+            try {
+                token.linkToDeath(new IBinder.DeathRecipient() {
+                    @Override public void binderDied() {
+                        downloadServiceInactive();
+                    }
+                }, 0);
+            } catch (RemoteException e) {
+                mDownloadServiceActive = null;
+            }
+        }
+    }
+
+    void downloadServiceInactive() {
+        synchronized (this) {
+            mDownloadServiceActive = null;
+            exitMaintenanceEarlyIfNeededLocked();
+        }
+    }
+
+    void setSyncActive(boolean active) {
+        synchronized (this) {
+            mSyncActive = active;
+            if (!active) {
+                exitMaintenanceEarlyIfNeededLocked();
+            }
+        }
+    }
+
+    void setJobsActive(boolean active) {
+        synchronized (this) {
+            mJobsActive = active;
+            if (!active) {
+                exitMaintenanceEarlyIfNeededLocked();
+            }
+        }
+    }
+
+    void setAlarmsActive(boolean active) {
+        synchronized (this) {
+            mAlarmsActive = active;
+            if (!active) {
+                exitMaintenanceEarlyIfNeededLocked();
+            }
+        }
+    }
+
+    void exitMaintenanceEarlyIfNeededLocked() {
+        if (mState == STATE_IDLE_MAINTENANCE || mLightState == LIGHT_STATE_IDLE_MAINTENANCE) {
+            if (mActiveIdleOpCount <= 0 && mDownloadServiceActive == null
+                    && !mSyncActive && !mJobsActive && !mAlarmsActive) {
+                if (mState == STATE_IDLE_MAINTENANCE) {
+                    stepIdleStateLocked("s:early");
+                } else {
+                    stepLightIdleStateLocked("s:early");
+                }
+            }
+        }
+    }
+
     void motionLocked() {
         if (DEBUG) Slog.d(TAG, "motionLocked()");
         // The motion sensor will have been disabled at this point
@@ -1612,7 +1736,7 @@
         }
         mLocated = true;
         if (mNotMoving) {
-            stepIdleStateLocked();
+            stepIdleStateLocked("s:location");
         }
     }
 
@@ -1628,7 +1752,7 @@
         }
         mLocated = true;
         if (mNotMoving) {
-            stepIdleStateLocked();
+            stepIdleStateLocked("s:gps");
         }
     }
 
@@ -1933,7 +2057,7 @@
                 long token = Binder.clearCallingIdentity();
                 try {
                     exitForceIdleLocked();
-                    stepIdleStateLocked();
+                    stepIdleStateLocked("s:shell");
                     pw.print("Stepped to: ");
                     pw.println(stateToString(mState));
                 } finally {
@@ -1947,7 +2071,7 @@
                 long token = Binder.clearCallingIdentity();
                 try {
                     exitForceIdleLocked();
-                    stepLightIdleStateLocked();
+                    stepLightIdleStateLocked("s:shell");
                     pw.print("Stepped to: "); pw.println(lightStateToString(mLightState));
                 } finally {
                     Binder.restoreCallingIdentity(token);
@@ -1967,7 +2091,7 @@
                     becomeInactiveIfAppropriateLocked();
                     int curState = mState;
                     while (curState != STATE_IDLE) {
-                        stepIdleStateLocked();
+                        stepIdleStateLocked("s:shell");
                         if (curState == mState) {
                             pw.print("Unable to go idle; stopped at ");
                             pw.println(stateToString(mState));
@@ -2226,6 +2350,9 @@
             pw.println(lightStateToString(mLightState));
             pw.print("  mInactiveTimeout="); TimeUtils.formatDuration(mInactiveTimeout, pw);
             pw.println();
+            if (mActiveIdleOpCount != 0) {
+                pw.print("  mActiveIdleOpCount="); pw.println(mActiveIdleOpCount);
+            }
             if (mNextAlarmTime != 0) {
                 pw.print("  mNextAlarmTime=");
                 TimeUtils.formatDuration(mNextAlarmTime, SystemClock.elapsedRealtime(), pw);
@@ -2246,6 +2373,18 @@
                 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
                 pw.println();
             }
+            if (mSyncActive) {
+                pw.print("  mSyncActive="); pw.println(mSyncActive);
+            }
+            if (mJobsActive) {
+                pw.print("  mJobsActive="); pw.println(mJobsActive);
+            }
+            if (mAlarmsActive) {
+                pw.print("  mAlarmsActive="); pw.println(mAlarmsActive);
+            }
+            if (mDownloadServiceActive != null) {
+                pw.print("  mDownloadServiceActive="); pw.println(mDownloadServiceActive);
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 3359060..43d10c7 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -226,7 +226,7 @@
             final int N = a.length;
             boolean printedHeader = false;
             F filter;
-            if (collapseDuplicates) {
+            if (collapseDuplicates && !printFilter) {
                 found.clear();
                 for (int i=0; i<N && (filter=a[i]) != null; i++) {
                     if (packageName != null && !isPackageForFilter(packageName, filter)) {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 50afa3c..f89155d 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -56,6 +56,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -96,6 +97,7 @@
 import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.NativeDaemonConnector.Command;
@@ -119,6 +121,7 @@
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.KeySpec;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -284,6 +287,8 @@
 
     @GuardedBy("mLock")
     private int[] mStartedUsers = EmptyArray.INT;
+    @GuardedBy("mLock")
+    private int[] mUnlockedUsers = EmptyArray.INT;
 
     /** Map from disk ID to disk */
     @GuardedBy("mLock")
@@ -402,6 +407,17 @@
         }
     }
 
+    private static String escapeNull(String arg) {
+        if (TextUtils.isEmpty(arg)) {
+            return "!";
+        } else {
+            if (arg.indexOf('\0') != -1 || arg.indexOf(' ') != -1) {
+                throw new IllegalArgumentException(arg);
+            }
+            return arg;
+        }
+    }
+
     /** List of crypto types.
       * These must match CRYPT_TYPE_XXX in cryptfs.h AND their
       * corresponding commands in CommandListener.cpp */
@@ -1892,6 +1908,9 @@
             if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) {
                 mForceAdoptable = (flags & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0;
             }
+            if ((mask & StorageManager.DEBUG_EMULATE_FBE) != 0) {
+                // TODO: persist through vold and reboot
+            }
 
             writeSettingsLocked();
             mHandler.obtainMessage(H_RESET).sendToTarget();
@@ -2597,6 +2616,24 @@
         }
     }
 
+    /**
+     * Is userdata convertible to file based encryption?
+     * @return non zero for convertible
+     */
+    @Override
+    public boolean isConvertibleToFBE() throws RemoteException {
+
+        waitForReady();
+
+        final NativeDaemonEvent event;
+        try {
+            event = mCryptConnector.execute("cryptfs", "isConvertibleToFBE");
+            return Integer.parseInt(event.getMessage()) != 0;
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
     @Override
     public String getPassword() throws RemoteException {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE,
@@ -2636,65 +2673,105 @@
     }
 
     @Override
-    public void createNewUserDir(int userHandle, String path) {
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("Only SYSTEM_UID can create user directories");
-        }
-
+    public void createUserKey(int userId, int serialNumber) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
         waitForReady();
 
-        if (DEBUG_EVENTS) {
-            Slog.i(TAG, "Creating new user dir");
-        }
-
         try {
-            NativeDaemonEvent event = mCryptConnector.execute(
-                "cryptfs", "createnewuserdir", userHandle, path);
-            if (!"0".equals(event.getMessage())) {
-                String error = "createnewuserdir sent unexpected message: "
-                    + event.getMessage();
-                Slog.e(TAG,  error);
-                // ext4enc:TODO is this the right exception?
-                throw new RuntimeException(error);
-            }
+            mCryptConnector.execute("cryptfs", "create_user_key", userId, serialNumber);
         } catch (NativeDaemonConnectorException e) {
-            Slog.e(TAG, "createnewuserdir threw exception", e);
-            throw new RuntimeException("createnewuserdir threw exception", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
-    // ext4enc:TODO duplication between this and createNewUserDir is nasty
     @Override
-    public void deleteUserKey(int userHandle) {
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("Only SYSTEM_UID can delete user keys");
-        }
-
+    public void destroyUserKey(int userId) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
         waitForReady();
 
-        if (DEBUG_EVENTS) {
-            Slog.i(TAG, "Deleting user key");
+        try {
+            mCryptConnector.execute("cryptfs", "destroy_user_key", userId);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void unlockUserKey(int userId, int serialNumber, byte[] token) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+        waitForReady();
+
+        final String encodedToken;
+        if (ArrayUtils.isEmpty(token)) {
+            encodedToken = "!";
+        } else {
+            encodedToken = HexDump.toHexString(token);
         }
 
         try {
-            NativeDaemonEvent event = mCryptConnector.execute(
-                "cryptfs", "deleteuserkey", userHandle);
-            if (!"0".equals(event.getMessage())) {
-                String error = "deleteuserkey sent unexpected message: "
-                    + event.getMessage();
-                Slog.e(TAG,  error);
-                // ext4enc:TODO is this the right exception?
-                throw new RuntimeException(error);
-            }
+            mCryptConnector.execute("cryptfs", "unlock_user_key", userId, serialNumber,
+                    new SensitiveArg(encodedToken));
         } catch (NativeDaemonConnectorException e) {
-            Slog.e(TAG, "deleteuserkey threw exception", e);
-            throw new RuntimeException("deleteuserkey threw exception", e);
+            throw e.rethrowAsParcelableException();
+        }
+
+        synchronized (mLock) {
+            mUnlockedUsers = ArrayUtils.appendInt(mUnlockedUsers, userId);
+        }
+    }
+
+    @Override
+    public void lockUserKey(int userId) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+        waitForReady();
+
+        try {
+            mCryptConnector.execute("cryptfs", "lock_user_key", userId);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+
+        synchronized (mLock) {
+            mUnlockedUsers = ArrayUtils.removeInt(mUnlockedUsers, userId);
+        }
+    }
+
+    @Override
+    public boolean isUserKeyUnlocked(int userId) {
+        if (SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false)) {
+            synchronized (mLock) {
+                return ArrayUtils.contains(mUnlockedUsers, userId);
+            }
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+        waitForReady();
+
+        try {
+            mCryptConnector.execute("cryptfs", "prepare_user_storage", escapeNull(volumeUuid),
+                    userId, serialNumber);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
         }
     }
 
     @Override
     public boolean isPerUserEncryptionEnabled() {
-        return "file".equals(SystemProperties.get("ro.crypto.type", "none"));
+        // TODO: switch this over to a single property; currently using two to
+        // handle the emulated case
+        return "file".equals(SystemProperties.get("ro.crypto.type", "none"))
+                || SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false);
+    }
+
+    @Override
+    public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException {
+        // TODO: Invoke vold to mount app fuse.
+        throw new UnsupportedOperationException();
     }
 
     @Override
@@ -3431,6 +3508,9 @@
             pw.println();
             pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
             pw.println("Force adoptable: " + mForceAdoptable);
+            pw.println();
+            pw.println("Started users: " + Arrays.toString(mStartedUsers));
+            pw.println("Unlocked users: " + Arrays.toString(mUnlockedUsers));
         }
 
         synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 1ff13b2..9ac4ba3 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -980,7 +980,7 @@
             if (user.isRestricted() && (parentUserId == user.restrictedProfileParentId)) {
                 addSharedAccountAsUser(account, user.id);
                 try {
-                    if (ActivityManagerNative.getDefault().isUserRunning(user.id, false)) {
+                    if (ActivityManagerNative.getDefault().isUserRunning(user.id, 0)) {
                         mMessageHandler.sendMessage(mMessageHandler.obtainMessage(
                                 MESSAGE_COPY_SHARED_ACCOUNT, parentUserId, user.id, account));
                     }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index befaaef..30565c6 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1527,7 +1527,7 @@
             synchronized (r.stats.getBatteryStats()) {
                 r.stats.startLaunchedLocked();
             }
-            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
+            mAm.notifyPackageUse(r.serviceInfo.packageName);
             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
             app.thread.scheduleCreateService(r, r.serviceInfo,
                     mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
@@ -2334,7 +2334,7 @@
                         sr.userId, sr.crashCount, sr.shortName, app.pid);
                 bringDownServiceLocked(sr);
             } else if (!allowRestart
-                    || !mAm.mUserController.isUserRunningLocked(sr.userId, false)) {
+                    || !mAm.mUserController.isUserRunningLocked(sr.userId, 0)) {
                 bringDownServiceLocked(sr);
             } else {
                 boolean canceled = scheduleServiceRestartLocked(sr, true);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 03d7247..c1413ff 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -114,6 +114,7 @@
 import com.android.server.SystemServiceManager;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.am.ActivityStackSupervisor.ActivityDisplay;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.pm.Installer;
 import com.android.server.pm.UserManagerService;
@@ -134,6 +135,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.SleepToken;
 import android.app.ActivityManagerNative;
@@ -330,6 +332,11 @@
     // before we decide it must be hung.
     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
 
+    // How long we will retain processes hosting content providers in the "last activity"
+    // state before allowing them to drop down to the regular cached LRU list.  This is
+    // to avoid thrashing of provider processes under low memory situations.
+    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
+
     // How long we wait for a launched process to attach to the activity manager
     // before we decide it's never going to come up for real, when the process was
     // started with a wrapper for instrumentation (such as Valgrind) because it
@@ -3060,12 +3067,10 @@
         return proc;
     }
 
-    void ensurePackageDexOpt(String packageName) {
+    void notifyPackageUse(String packageName) {
         IPackageManager pm = AppGlobals.getPackageManager();
         try {
-            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
-                mDidDexOpt = true;
-            }
+            pm.notifyPackageUse(packageName);
         } catch (RemoteException e) {
         }
     }
@@ -4174,13 +4179,15 @@
                         "startActivityFromRecentsInner: Task " + taskId + " not found.");
             }
 
-            if (launchStackId != INVALID_STACK_ID && task.stack.mStackId != launchStackId) {
+            if (launchStackId != INVALID_STACK_ID) {
                 if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
                     ActivityOptions activityOptions = new ActivityOptions(bOptions);
                     mWindowManager.setDockedStackCreateMode(activityOptions.getDockCreateMode());
                 }
-                mStackSupervisor.moveTaskToStackLocked(
-                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents");
+                if (task.stack.mStackId != launchStackId) {
+                    mStackSupervisor.moveTaskToStackLocked(
+                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents");
+                }
             }
 
             if (task.getRootActivity() != null) {
@@ -5319,7 +5326,7 @@
                         Slog.w(TAG, "Failed trying to unstop package "
                                 + packageName + ": " + e);
                     }
-                    if (mUserController.isUserRunningLocked(user, false)) {
+                    if (mUserController.isUserRunningLocked(user, 0)) {
                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
                     }
                 }
@@ -6123,11 +6130,11 @@
                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
             }
 
-            ensurePackageDexOpt(app.instrumentationInfo != null
+            notifyPackageUse(app.instrumentationInfo != null
                     ? app.instrumentationInfo.packageName
                     : app.info.packageName);
             if (app.instrumentationClass != null) {
-                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
+                notifyPackageUse(app.instrumentationClass.getPackageName());
             }
             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
                     + processName + " with config " + mConfiguration);
@@ -6207,7 +6214,7 @@
         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
                     "New app is backup target, launching agent for " + app);
-            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
+            notifyPackageUse(mBackupTarget.appInfo.packageName);
             try {
                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
@@ -8566,8 +8573,16 @@
                     }
                 }
 
+                // Use the full screen as the context for the task thumbnail
+                final Point displaySize = new Point();
+                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
+                r.task.stack.getDisplaySize(displaySize);
+                thumbnailInfo.taskWidth = displaySize.x;
+                thumbnailInfo.taskHeight = displaySize.y;
+                thumbnailInfo.screenOrientation = mConfiguration.orientation;
+
                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
-                        intent, description);
+                        intent, description, thumbnailInfo);
 
                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
                 if (trimIdx >= 0) {
@@ -8586,7 +8601,7 @@
                 mRecentTasks.add(task);
                 r.task.stack.addTask(task, false, false);
 
-                task.setLastThumbnail(thumbnail);
+                task.setLastThumbnailLocked(thumbnail);
                 task.freeLastThumbnail();
 
                 return task.taskId;
@@ -8681,12 +8696,25 @@
         Rect rect = new Rect();
         try {
             synchronized (this) {
-                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
+                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
                 if (task == null) {
                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
                     return rect;
                 }
-                mWindowManager.getTaskBounds(task.taskId, rect);
+                if (task.stack != null) {
+                    // Return the bounds from window manager since it will be adjusted for various
+                    // things like the presense of a docked stack for tasks that aren't resizeable.
+                    mWindowManager.getTaskBounds(task.taskId, rect);
+                } else {
+                    // Task isn't in window manager yet since it isn't associated with a stack.
+                    // Return the persist value from activity manager
+                    if (task.mBounds != null) {
+                        rect.set(task.mBounds);
+                    } else if (task.mLastNonFullscreenBounds != null) {
+                        rect.set(task.mLastNonFullscreenBounds);
+                    }
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -9438,7 +9466,7 @@
                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
                             mProcessStats);
                 }
-                ensurePackageDexOpt(cpi.applicationInfo.packageName);
+                notifyPackageUse(cpi.applicationInfo.packageName);
             }
         }
         return providers;
@@ -9614,6 +9642,14 @@
             if (conn.stableCount == 0 && conn.unstableCount == 0) {
                 cpr.connections.remove(conn);
                 conn.client.conProviders.remove(conn);
+                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
+                    // The client is more important than last activity -- note the time this
+                    // is happening, so we keep the old provider process around a bit as last
+                    // activity to avoid thrashing it.
+                    if (cpr.proc != null) {
+                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
+                    }
+                }
                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
                 return true;
             }
@@ -9803,7 +9839,7 @@
 
                 // Make sure that the user who owns this provider is running.  If not,
                 // we don't want to allow it to run.
-                if (!mUserController.isUserRunningLocked(userId, false)) {
+                if (!mUserController.isUserRunningLocked(userId, 0)) {
                     Slog.w(TAG, "Unable to launch app "
                             + cpi.applicationInfo.packageName + "/"
                             + cpi.applicationInfo.uid + " for provider "
@@ -12057,8 +12093,6 @@
                 }
             }
 
-            enableSystemUserApps();
-
             // Start up initial activity.
             mBooting = true;
             startHomeActivityLocked(currentUserId, "systemReady");
@@ -12110,43 +12144,6 @@
         }
     }
 
-    private void enableSystemUserApps() {
-        // For system user, enable apps based on the following conditions:
-        // - app is whitelisted; or has no launcher icons; or has INTERACT_ACROSS_USERS permission
-        // - app is not in the blacklist
-        if (UserManager.isSplitSystemUser()) {
-            AppsQueryHelper queryHelper = new AppsQueryHelper(mContext);
-            Set<String> enableApps = new HashSet<>();
-            enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
-                            | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
-                            | AppsQueryHelper.GET_DEFAULT_IMES,
-                            /* systemAppsOnly */ true, UserHandle.SYSTEM));
-            ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
-            enableApps.addAll(wlApps);
-            ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
-            enableApps.removeAll(blApps);
-
-            List<String> systemApps = queryHelper.queryApps(0, /* systemAppsOnly */ true,
-                    UserHandle.SYSTEM);
-            final int systemAppsSize = systemApps.size();
-            for (int i = 0; i < systemAppsSize; i++) {
-                String pName = systemApps.get(i);
-                boolean enable = enableApps.contains(pName);
-                try {
-                    if (enable) {
-                        AppGlobals.getPackageManager().installExistingPackageAsUser(pName,
-                                UserHandle.USER_SYSTEM);
-                    } else {
-                        AppGlobals.getPackageManager().deletePackageAsUser(pName, null,
-                                UserHandle.USER_SYSTEM, PackageManager.DELETE_SYSTEM_APP);
-                    }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Error occured when processing package " + pName, e);
-                }
-            }
-        }
-    }
-
     private boolean makeAppCrashingLocked(ProcessRecord app,
             String shortMsg, String longMsg, String stackTrace) {
         app.crashing = true;
@@ -16631,7 +16628,7 @@
         // If not, we will just skip it. Make an exception for shutdown broadcasts
         // and upgrade steps.
 
-        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, false)) {
+        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
             if ((callingUid != Process.SYSTEM_UID
                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
@@ -17435,14 +17432,16 @@
             throw new IllegalArgumentException("Removing home stack is not allowed.");
         }
         synchronized (this) {
+            long origId = Binder.clearCallingIdentity();
             ActivityStack stack = mStackSupervisor.getStack(stackId);
             if (stack != null) {
                 ArrayList<TaskRecord> tasks = stack.getAllTasks();
                 for (int i = tasks.size() - 1; i >= 0; i--) {
-                    removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
+                    removeTaskByIdLocked(tasks.get(i).taskId, false /* killProcess */,
                             !REMOVE_FROM_RECENTS);
                 }
             }
+            Binder.restoreCallingIdentity(origId);
         }
     }
 
@@ -18366,6 +18365,18 @@
             }
         }
 
+        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
+            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
+                adj = ProcessList.PREVIOUS_APP_ADJ;
+                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+                app.cached = false;
+                app.adjType = "provider";
+            }
+            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
+                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+            }
+        }
+
         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
             // A client of one of our services or providers is in the top state.  We
             // *may* want to be in the top state, but not if we are already running in
@@ -18874,8 +18885,6 @@
                         }
                     }
                 }
-                Process.setSwappiness(app.pid,
-                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
             }
         }
         if (app.repForegroundActivities != app.foregroundActivities) {
@@ -19980,7 +19989,7 @@
     }
 
     @Override
-    public boolean isUserRunning(int userId, boolean orStopped) {
+    public boolean isUserRunning(int userId, int flags) {
         if (checkCallingPermission(INTERACT_ACROSS_USERS)
                 != PackageManager.PERMISSION_GRANTED) {
             String msg = "Permission Denial: isUserRunning() from pid="
@@ -19991,7 +20000,7 @@
             throw new SecurityException(msg);
         }
         synchronized (this) {
-            return mUserController.isUserRunningLocked(userId, orStopped);
+            return mUserController.isUserRunningLocked(userId, flags);
         }
     }
 
@@ -20021,17 +20030,10 @@
         mUserController.unregisterUserSwitchObserver(observer);
     }
 
-    private int applyUserId(int uid, int userId) {
-        return UserHandle.getUid(userId, uid);
-    }
-
     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
         if (info == null) return null;
         ApplicationInfo newInfo = new ApplicationInfo(info);
-        newInfo.uid = applyUserId(info.uid, userId);
-        newInfo.dataDir = Environment
-                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
-                .getAbsolutePath();
+        newInfo.initForUser(userId);
         return newInfo;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d1e7e85..13c1417 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -73,7 +73,7 @@
         String opt;
         while ((opt = getNextOption()) != null) {
             if (opt.equals("--user")) {
-                userId = parseUserArg(getNextArgRequired());
+                userId = UserHandle.parseUserArg(getNextArgRequired());
             } else {
                 pw.println("Error: Unknown option: " + opt);
                 return -1;
@@ -89,7 +89,7 @@
         String opt;
         while ((opt=getNextOption()) != null) {
             if (opt.equals("--user")) {
-                userId = parseUserArg(getNextArgRequired());
+                userId = UserHandle.parseUserArg(getNextArgRequired());
             } else {
                 pw.println("Error: Unknown option: " + opt);
                 return -1;
@@ -141,22 +141,6 @@
         return 0;
     }
 
-    int parseUserArg(String arg) {
-        int userId;
-        if ("all".equals(arg)) {
-            userId = UserHandle.USER_ALL;
-        } else if ("current".equals(arg) || "cur".equals(arg)) {
-            userId = UserHandle.USER_CURRENT;
-        } else {
-            try {
-                userId = Integer.parseInt(arg);
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException("Bad user number: " + arg);
-            }
-        }
-        return userId;
-    }
-
     @Override
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 9278a90..aa04bd7 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -932,7 +932,7 @@
         if (newThumbnail != null) {
             if (DEBUG_THUMBNAILS) Slog.i(TAG_THUMBNAILS,
                     "Setting thumbnail of " + this + " to " + newThumbnail);
-            boolean thumbnailUpdated = task.setLastThumbnail(newThumbnail);
+            boolean thumbnailUpdated = task.setLastThumbnailLocked(newThumbnail);
             if (thumbnailUpdated && isPersistable()) {
                 mStackSupervisor.mService.notifyTaskPersisterLocked(task, false);
             }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 6b8bdf8..e28d198 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -31,6 +31,7 @@
 import static com.android.server.am.ActivityStackSupervisor.MOVING;
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
 
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.ArraySet;
 
@@ -388,6 +389,10 @@
         mWindowManager.detachStack(mStackId);
     }
 
+    public void getDisplaySize(Point out) {
+        mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
+    }
+
     void setBounds(Rect bounds) {
         mBounds = mFullscreen ? null : new Rect(bounds);
         if (mTaskPositioner != null) {
@@ -1333,7 +1338,12 @@
             return topHomeActivity == null || !topHomeActivity.isHomeActivity();
         }
 
-        final int belowFocusedIndex = mStacks.indexOf(focusedStack) - 1;
+        // Find the first stack below focused stack that actually got something visible.
+        int belowFocusedIndex = mStacks.indexOf(focusedStack) - 1;
+        while (belowFocusedIndex >= 0 &&
+                mStacks.get(belowFocusedIndex).topRunningActivityLocked() == null) {
+            belowFocusedIndex--;
+        }
         if ((focusedStackId == DOCKED_STACK_ID || focusedStackId == PINNED_STACK_ID)
                 && stackIndex == belowFocusedIndex) {
             // Stacks directly behind the docked or pinned stack are always visible.
@@ -1408,19 +1418,9 @@
         if (top == null) {
             return;
         }
-        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                "ensureActivitiesVisible behind " + top
+        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
                 + " configChanges=0x" + Integer.toHexString(configChanges));
-
-        if (mTranslucentActivityWaiting != top) {
-            mUndrawnActivitiesBelowTopTranslucent.clear();
-            if (mTranslucentActivityWaiting != null) {
-                // Call the callback with a timeout indication.
-                notifyActivityDrawnLocked(null);
-                mTranslucentActivityWaiting = null;
-            }
-            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
-        }
+        checkTranslucentActivityWaiting(top);
 
         // If the top activity is not fullscreen, then we need to
         // make sure any activities under it are now visible.
@@ -1448,7 +1448,6 @@
                     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) {
@@ -1456,143 +1455,28 @@
                     }
 
                     if (r.app == null || r.app.thread == null) {
-                        // We need to make sure the app is running if it's the top, or it is
-                        // just made visible from invisible.
-                        // If the app is already visible, it must have died while it was visible.
-                        // In this case, we'll show the dead window but will not restart the app.
-                        // Otherwise we could end up thrashing.
-                        if (r == top || !r.visible) {
-                            // This activity needs to be visible, but isn't even running...
-                            // get it started and resume if no other stack in this stack is resumed.
-                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                                    "Start and freeze screen for " + r);
-                            if (r != starting) {
-                                r.startFreezingScreenLocked(r.app, configChanges);
-                            }
-                            if (!r.visible || r.mLaunchTaskBehind) {
-                                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                                        "Starting and making visible: " + r);
-                                setVisible(r, true);
-                            }
-                            if (r != starting) {
-                                mStackSupervisor.startSpecificActivityLocked(
-                                        r, noStackActivityResumed, false);
-                                if (activityNdx >= activities.size()) {
-                                    // Record may be removed if its process needs to restart.
-                                    activityNdx = activities.size() - 1;
-                                } else {
-                                    noStackActivityResumed = false;
-                                }
+                        if (makeVisibleAndRestartIfNeeded(starting, configChanges, top,
+                                noStackActivityResumed, r)) {
+                            if (activityNdx >= activities.size()) {
+                                // Record may be removed if its process needs to restart.
+                                activityNdx = activities.size() - 1;
+                            } else {
+                                noStackActivityResumed = false;
                             }
                         }
                     } else if (r.visible) {
-                        // If this activity is already visible, then there is nothing
-                        // else to do here.
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                                "Skipping: already visible at " + r);
-                        r.stopFreezingScreenLocked(false);
-                        try {
-                            if (r.returningOptions != null) {
-                                r.app.thread.scheduleOnNewActivityOptions(r.appToken,
-                                        r.returningOptions);
-                            }
-                        } catch(RemoteException e) {
-                        }
-                        if (r.state == ActivityState.RESUMED) {
+                        if (alreadyVisible(r)) {
                             noStackActivityResumed = false;
                         }
                     } else {
-                        // This activity is not currently visible, but is running.
-                        // Tell it to become visible.
-                        r.visible = true;
-                        if (r.state != ActivityState.RESUMED && r != starting) {
-                            // If this activity is paused, tell it
-                            // to now show its window.
-                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                                    "Making visible and scheduling visibility: " + r);
-                            try {
-                                if (mTranslucentActivityWaiting != null) {
-                                    r.updateOptionsLocked(r.returningOptions);
-                                    mUndrawnActivitiesBelowTopTranslucent.add(r);
-                                }
-                                setVisible(r, true);
-                                r.sleeping = false;
-                                r.app.pendingUiClean = true;
-                                r.app.thread.scheduleWindowVisibility(r.appToken, true);
-                                r.stopFreezingScreenLocked(false);
-                            } catch (Exception e) {
-                                // Just skip on any failure; we'll make it
-                                // visible when it next restarts.
-                                Slog.w(TAG, "Exception thrown making visibile: "
-                                        + r.intent.getComponent(), e);
-                            }
-                        }
+                        becomeVisible(starting, r);
                     }
-
                     // Aggregate current change flags.
                     configChanges |= r.configChangeFlags;
-
-                    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()) {
-                        behindFullscreenActivity = true;
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
-                                + " stackInvisible=" + stackInvisible
-                                + " behindFullscreenActivity=" + behindFullscreenActivity);
-                    }
+                    behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
+                            behindFullscreenActivity, task, r);
                 } else {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                            "Make invisible? " + r + " finishing=" + r.finishing
-                            + " state=" + r.state + " stackInvisible=" + stackInvisible
-                            + " behindFullscreenActivity=" + behindFullscreenActivity);
-                    // Now for any activities that aren't visible to the user, make
-                    // sure they no longer are keeping the screen frozen.
-                    if (r.visible) {
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r);
-                        try {
-                            setVisible(r, false);
-                            switch (r.state) {
-                                case STOPPING:
-                                case STOPPED:
-                                    if (r.app != null && r.app.thread != null) {
-                                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                                                "Scheduling invisibility: " + r);
-                                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
-                                    }
-                                    break;
-
-                                case INITIALIZING:
-                                case RESUMED:
-                                case PAUSING:
-                                case PAUSED:
-                                    // This case created for transitioning activities from
-                                    // translucent to opaque {@link Activity#convertToOpaque}.
-                                    if (getVisibleBehindActivity() == r) {
-                                        releaseBackgroundResources(r);
-                                    } else {
-                                        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
-                                            mStackSupervisor.mStoppingActivities.add(r);
-                                        }
-                                        mStackSupervisor.scheduleIdleLocked();
-                                    }
-                                    break;
-
-                                default:
-                                    break;
-                            }
-                        } catch (Exception e) {
-                            // Just skip on any failure; we'll make it
-                            // visible when it next restarts.
-                            Slog.w(TAG, "Exception thrown making hidden: "
-                                    + r.intent.getComponent(), e);
-                        }
-                    } else {
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
-                    }
+                    becomeInvisible(stackInvisible, behindFullscreenActivity, r);
                 }
             }
             if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
@@ -1610,6 +1494,147 @@
         }
     }
 
+    private void checkTranslucentActivityWaiting(ActivityRecord top) {
+        if (mTranslucentActivityWaiting != top) {
+            mUndrawnActivitiesBelowTopTranslucent.clear();
+            if (mTranslucentActivityWaiting != null) {
+                // Call the callback with a timeout indication.
+                notifyActivityDrawnLocked(null);
+                mTranslucentActivityWaiting = null;
+            }
+            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
+        }
+    }
+
+    private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
+            ActivityRecord top, boolean noStackActivityResumed, ActivityRecord r) {
+        // We need to make sure the app is running if it's the top, or it is just made visible from
+        // invisible. If the app is already visible, it must have died while it was visible. In this
+        // case, we'll show the dead window but will not restart the app. Otherwise we could end up
+        // thrashing.
+        if (r == top || !r.visible) {
+            // This activity needs to be visible, but isn't even running...
+            // get it started and resume if no other stack in this stack is resumed.
+            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
+            if (r != starting) {
+                r.startFreezingScreenLocked(r.app, configChanges);
+            }
+            if (!r.visible || r.mLaunchTaskBehind) {
+                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
+                setVisible(r, true);
+            }
+            if (r != starting) {
+                mStackSupervisor.startSpecificActivityLocked(r, noStackActivityResumed, false);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void becomeInvisible(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);
+        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);
+        try {
+            setVisible(r, false);
+            switch (r.state) {
+                case STOPPING:
+                case STOPPED:
+                    if (r.app != null && r.app.thread != null) {
+                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+                                "Scheduling invisibility: " + r);
+                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
+                    }
+                    break;
+
+                case INITIALIZING:
+                case RESUMED:
+                case PAUSING:
+                case PAUSED:
+                    // This case created for transitioning activities from
+                    // translucent to opaque {@link Activity#convertToOpaque}.
+                    if (getVisibleBehindActivity() == r) {
+                        releaseBackgroundResources(r);
+                    } else {
+                        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
+                            mStackSupervisor.mStoppingActivities.add(r);
+                        }
+                        mStackSupervisor.scheduleIdleLocked();
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+        } catch (Exception e) {
+            // Just skip on any failure; we'll make it visible when it next restarts.
+            Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e);
+        }
+    }
+
+    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()) {
+            behindFullscreenActivity = true;
+            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
+                    + " stackInvisible=" + stackInvisible
+                    + " behindFullscreenActivity=" + behindFullscreenActivity);
+        }
+        return behindFullscreenActivity;
+    }
+
+    private void becomeVisible(ActivityRecord starting, ActivityRecord r) {
+        // This activity is not currently visible, but is running. Tell it to become visible.
+        r.visible = true;
+        if (r.state != ActivityState.RESUMED && r != starting) {
+            // If this activity is paused, tell it to now show its window.
+            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+                    "Making visible and scheduling visibility: " + r);
+            try {
+                if (mTranslucentActivityWaiting != null) {
+                    r.updateOptionsLocked(r.returningOptions);
+                    mUndrawnActivitiesBelowTopTranslucent.add(r);
+                }
+                setVisible(r, true);
+                r.sleeping = false;
+                r.app.pendingUiClean = true;
+                r.app.thread.scheduleWindowVisibility(r.appToken, true);
+                r.stopFreezingScreenLocked(false);
+            } catch (Exception e) {
+                // Just skip on any failure; we'll make it
+                // visible when it next restarts.
+                Slog.w(TAG, "Exception thrown making visibile: " + r.intent.getComponent(), e);
+            }
+        }
+    }
+
+    private boolean alreadyVisible(ActivityRecord r) {
+        // If this activity is already visible, then there is nothing else to do here.
+        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r);
+        r.stopFreezingScreenLocked(false);
+        try {
+            if (r.returningOptions != null) {
+                r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions);
+            }
+        } catch(RemoteException e) {
+        }
+        return r.state == ActivityState.RESUMED;
+    }
+
     void convertActivityToTranslucent(ActivityRecord r) {
         mTranslucentActivityWaiting = r;
         mUndrawnActivitiesBelowTopTranslucent.clear();
@@ -3098,6 +3123,9 @@
             // If the activity is PAUSING, we will complete the finish once
             // it is done pausing; else we can just directly finish it here.
             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
+            if (r.visible) {
+                mWindowManager.setAppVisibility(r.appToken, false);
+            }
             return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
         } else {
             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
@@ -4539,6 +4567,11 @@
         if (!moving) {
             mStackSupervisor.removeLockedTaskLocked(task);
             mWindowManager.removeTask(task.taskId);
+            if (!StackId.persistTaskBounds(mStackId)) {
+                // Reset current bounds for task whose bounds shouldn't be persisted so it uses
+                // default configuration the next time it launches.
+                task.updateOverrideConfiguration(null);
+            }
         }
 
         final ActivityRecord r = mResumedActivity;
@@ -4601,14 +4634,20 @@
                 voiceInteractor);
         // add the task to stack first, mTaskPositioner might need the stack association
         addTask(task, toTop, false);
-        if (mTaskPositioner != null) {
-            mTaskPositioner.updateDefaultBounds(task, mTaskHistory, info.layout);
-        } else if (mBounds != null && task.mResizeable) {
+        if (!layoutTaskInStack(task, info.layout) && mBounds != null && task.mResizeable) {
             task.updateOverrideConfiguration(mBounds);
         }
         return task;
     }
 
+    boolean layoutTaskInStack(TaskRecord task, ActivityInfo.Layout layout) {
+        if (mTaskPositioner == null) {
+            return false;
+        }
+        mTaskPositioner.updateDefaultBounds(task, mTaskHistory, layout);
+        return true;
+    }
+
     ArrayList<TaskRecord> getAllTasks() {
         return new ArrayList<>(mTaskHistory);
     }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index fb2c7b1..0ec4b18 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1294,7 +1294,7 @@
                 // Home process is the root process of the task.
                 mService.mHomeProcess = task.mActivities.get(0).app;
             }
-            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
+            mService.notifyPackageUse(r.intent.getComponent().getPackageName());
             r.sleeping = false;
             r.forceNewConfig = false;
             mService.showAskCompatModeDialogLocked(r);
@@ -3272,7 +3272,7 @@
             task.stack.removeTask(task, "restoreRecentTaskLocked", MOVING);
         }
 
-        ActivityStack stack =
+        final ActivityStack stack =
                 getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
 
         if (stack == null) {
@@ -3339,31 +3339,35 @@
             Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
             return;
         }
-        if (StackId.preserveWindowOnTaskMove(stackId)) {
+
+        if (task.stack != null && task.stack.mStackId == stackId) {
+            // You are already in the right stack silly...
+            Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId);
+            return;
+        }
+
+        final ActivityRecord topActivity = task.getTopActivity();
+        if (StackId.preserveWindowOnTaskMove(stackId) && topActivity != null) {
             // We are about to relaunch the activity because its configuration changed due to
             // being maximized, i.e. size change. The activity will first remove the old window
             // and then add a new one. This call will tell window manager about this, so it can
             // preserve the old window until the new one is drawn. This prevents having a gap
             // between the removal and addition, in which no window is visible. We also want the
             // entrance of the new window to be properly animated.
-            ActivityRecord r = task.getTopActivity();
-            mWindowManager.setReplacingWindow(r.appToken, true /* animate */);
+            mWindowManager.setReplacingWindow(topActivity.appToken);
         }
-        final ActivityStack stack =
-                moveTaskToStackUncheckedLocked(task, stackId, toTop, forceFocus,
-                        "moveTaskToStack:" + reason);
+        final ActivityStack stack = moveTaskToStackUncheckedLocked(
+                task, stackId, toTop, forceFocus, "moveTaskToStack:" + reason);
 
         // Make sure the task has the appropriate bounds/size for the stack it is in.
         if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
-            resizeTaskLocked(task, stack.mBounds,
-                    RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
+            resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
         } else if (stackId == FREEFORM_WORKSPACE_STACK_ID
                 && task.mBounds == null && task.mLastNonFullscreenBounds != null) {
             resizeTaskLocked(task, task.mLastNonFullscreenBounds,
                     RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
         } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
-            resizeTaskLocked(task, stack.mBounds,
-                    RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
+            resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
         }
 
         // The task might have already been running and its visibility needs to be synchronized with
@@ -3419,9 +3423,12 @@
             Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
             return;
         }
-        ActivityStack stack =
-                getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
-        mWindowManager.positionTaskInStack(taskId, stackId, position);
+        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
+
+        task.updateOverrideConfigurationForStack(stack);
+
+        mWindowManager.positionTaskInStack(
+                taskId, stackId, position, task.mBounds, task.mOverrideConfig);
         final boolean stackChanged = task.stack != null && task.stack != stack;
         if (stackChanged) {
             task.stack.removeTask(task, "moveTaskToStack", MOVING);
@@ -3680,7 +3687,7 @@
     void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
         r.mLaunchTaskBehind = false;
         final TaskRecord task = r.task;
-        task.setLastThumbnail(task.stack.screenshotActivities(r));
+        task.setLastThumbnailLocked(task.stack.screenshotActivities(r));
         mRecentTasks.addLocked(task);
         mService.notifyTaskStackChangedLocked();
         mWindowManager.setAppVisibility(r.appToken, false);
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 6de8579..d317791 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -269,7 +269,7 @@
             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
                     "Delivering to component " + r.curComponent
                     + ": " + r);
-            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
+            mService.notifyPackageUse(r.intent.getComponent().getPackageName());
             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
                     mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
                     r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b77eec8..4bfe300 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -136,6 +136,7 @@
     long curCpuTime;            // How long proc has run CPU most recently
     long lastRequestedGc;       // When we last asked the app to do a gc
     long lastLowMemory;         // When we last told the app that memory is low
+    long lastProviderTime;      // The last time someone else was using a provider in this process.
     boolean reportLowMemory;    // Set to true when waiting to report low mem
     boolean empty;              // Is this an empty background process?
     boolean cached;             // Is this a cached process?
@@ -317,6 +318,11 @@
                     pw.print(" foregroundActivities="); pw.print(foregroundActivities);
                     pw.print(" (rep="); pw.print(repForegroundActivities); pw.println(")");
         }
+        if (lastProviderTime > 0) {
+            pw.print(prefix); pw.print("lastProviderTime=");
+            TimeUtils.formatDuration(lastProviderTime, now, pw);
+            pw.println();
+        }
         if (hasStartedServices) {
             pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
         }
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 862a973..c63eaac 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -462,10 +462,12 @@
                     final boolean sameActivity = task.realActivity != null
                             && tr.realActivity != null
                             && task.realActivity.equals(tr.realActivity);
-                    if (!sameActivity) {
+                    // If the document is open in another app or is not the same
+                    // document, we don't need to trim it.
+                    if (!sameActivity || !sameIntent) {
                         continue;
-                    }
-                    if (maxRecents > 0 && !doTrim) {
+                    // Otherwise only trim if we are over our max recents for this task
+                    } else if (maxRecents > 0 && !doTrim) {
                         --maxRecents;
                         continue;
                     }
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 871331b..150baf0 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -16,22 +16,14 @@
 
 package com.android.server.am;
 
-import android.app.ActivityManager;
-import android.app.AppGlobals;
-import android.content.ComponentName;
 import android.content.pm.IPackageManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Debug;
-import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.UserHandle;
-import android.text.format.DateUtils;
-import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.util.Xml;
 import android.os.Process;
 
@@ -51,14 +43,10 @@
 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;
 
-import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
-
 public class TaskPersister {
     static final String TAG = "TaskPersister";
     static final boolean DEBUG = false;
@@ -104,6 +92,7 @@
     private static class WriteQueueItem {}
     private static class TaskWriteQueueItem extends WriteQueueItem {
         final TaskRecord mTask;
+
         TaskWriteQueueItem(TaskRecord task) {
             mTask = task;
         }
@@ -111,6 +100,7 @@
     private static class ImageWriteQueueItem extends WriteQueueItem {
         final String mFilename;
         Bitmap mImage;
+
         ImageWriteQueueItem(String filename, Bitmap image) {
             mFilename = filename;
             mImage = image;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 5fd213f..b214080 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -19,6 +19,7 @@
 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;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
@@ -36,6 +37,8 @@
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.TaskThumbnail;
 import android.app.ActivityManager.TaskDescription;
+import android.app.ActivityManager.TaskThumbnail;
+import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.content.ComponentName;
@@ -46,6 +49,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.ParcelFileDescriptor;
@@ -193,6 +197,7 @@
     private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
     private final File mLastThumbnailFile; // File containing last thumbnail.
     private final String mFilename;
+    private TaskThumbnailInfo mLastThumbnailInfo;
     CharSequence lastDescription; // Last description captured for this item.
 
     int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
@@ -233,6 +238,7 @@
         mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                 TaskPersister.IMAGE_EXTENSION;
         mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
+        mLastThumbnailInfo = new TaskThumbnailInfo();
         taskId = _taskId;
         mAffiliatedTaskId = _taskId;
         voiceSession = _voiceSession;
@@ -246,11 +252,12 @@
     }
 
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
-            TaskDescription _taskDescription) {
+            TaskDescription _taskDescription, TaskThumbnailInfo thumbnailInfo) {
         mService = service;
         mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                 TaskPersister.IMAGE_EXTENSION;
         mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
+        mLastThumbnailInfo = thumbnailInfo;
         taskId = _taskId;
         mAffiliatedTaskId = _taskId;
         voiceSession = null;
@@ -281,12 +288,14 @@
             int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
             long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
             boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
-            int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
-            int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
+            TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
+            int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
+            boolean resizeable, boolean privileged) {
         mService = service;
         mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                 TaskPersister.IMAGE_EXTENSION;
         mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
+        mLastThumbnailInfo = lastThumbnailInfo;
         taskId = _taskId;
         intent = _intent;
         affinityIntent = _affinityIntent;
@@ -319,7 +328,7 @@
         mCallingPackage = callingPackage;
         mResizeable = resizeable || mService.mForceResizableActivites;
         mPrivileged = privileged;
-        ActivityInfo info = mActivities.get(0).info;
+        ActivityInfo info = (mActivities.size() > 0) ? mActivities.get(0).info : null;
         mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
     }
 
@@ -489,12 +498,40 @@
     }
 
     /**
-     * Sets the last thumbnail.
+     * Sets the last thumbnail with the current task bounds and the system orientation.
      * @return whether the thumbnail was set
      */
-    boolean setLastThumbnail(Bitmap thumbnail) {
+    boolean setLastThumbnailLocked(Bitmap thumbnail) {
+        final Configuration serviceConfig = mService.mConfiguration;
+        int taskWidth = 0;
+        int taskHeight = 0;
+        if (mBounds != null) {
+            // Non-fullscreen tasks
+            taskWidth = mBounds.width();
+            taskHeight = mBounds.height();
+        } else if (stack != null) {
+            // Fullscreen tasks
+            final Point displaySize = new Point();
+            stack.getDisplaySize(displaySize);
+            taskWidth = displaySize.x;
+            taskHeight = displaySize.y;
+        } else {
+            Slog.e(TAG, "setLastThumbnailLocked() called on Task without stack");
+        }
+        return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, serviceConfig.orientation);
+    }
+
+    /**
+     * Sets the last thumbnail with the current task bounds.
+     * @return whether the thumbnail was set
+     */
+    private boolean setLastThumbnailLocked(Bitmap thumbnail, int taskWidth, int taskHeight,
+            int screenOrientation) {
         if (mLastThumbnail != thumbnail) {
             mLastThumbnail = thumbnail;
+            mLastThumbnailInfo.taskWidth = taskWidth;
+            mLastThumbnailInfo.taskHeight = taskHeight;
+            mLastThumbnailInfo.screenOrientation = screenOrientation;
             if (thumbnail == null) {
                 if (mLastThumbnailFile != null) {
                     mLastThumbnailFile.delete();
@@ -509,6 +546,7 @@
 
     void getLastThumbnail(TaskThumbnail thumbs) {
         thumbs.mainThumbnail = mLastThumbnail;
+        thumbs.thumbnailInfo = mLastThumbnailInfo;
         thumbs.thumbnailFileDescriptor = null;
         if (mLastThumbnail == null) {
             thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
@@ -523,11 +561,18 @@
         }
     }
 
+    /**
+     * Removes in-memory thumbnail data when the max number of in-memory task thumbnails is reached.
+     */
     void freeLastThumbnail() {
         mLastThumbnail = null;
     }
 
+    /**
+     * Removes all associated thumbnail data when a task is removed or pruned from recents.
+     */
     void disposeThumbnail() {
+        mLastThumbnailInfo.reset();
         mLastThumbnail = null;
         lastDescription = null;
     }
@@ -572,9 +617,18 @@
         return null;
     }
 
+    void setFrontOfTask() {
+        setFrontOfTask(null);
+    }
+
     /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
-    final void setFrontOfTask() {
-        boolean foundFront = false;
+    void setFrontOfTask(ActivityRecord newTop) {
+        // If a top candidate is suggested by the caller, go ahead and use it and mark all others
+        // as not front. This is needed in situations where the current front activity in the
+        // task isn't finished yet and we want to set the front to the activity moved to the front
+        // of the task.
+        boolean foundFront = newTop != null ? true : false;
+
         final int numActivities = mActivities.size();
         for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
             final ActivityRecord r = mActivities.get(activityNdx);
@@ -591,6 +645,9 @@
             // activity, make the bottom activity front.
             mActivities.get(0).frontOfTask = true;
         }
+        if (newTop != null) {
+            newTop.frontOfTask = true;
+        }
     }
 
     /**
@@ -605,7 +662,7 @@
         mActivities.add(newTop);
         updateEffectiveIntent();
 
-        setFrontOfTask();
+        setFrontOfTask(newTop);
     }
 
     void addActivityAtBottom(ActivityRecord r) {
@@ -766,7 +823,7 @@
             final ActivityRecord resumedActivity = stack.mResumedActivity;
             if (resumedActivity != null && resumedActivity.task == this) {
                 final Bitmap thumbnail = stack.screenshotActivities(resumedActivity);
-                setLastThumbnail(thumbnail);
+                setLastThumbnailLocked(thumbnail);
             }
         }
         final TaskThumbnail taskThumbnail = new TaskThumbnail();
@@ -978,6 +1035,7 @@
         if (lastTaskDescription != null) {
             lastTaskDescription.saveToXml(out);
         }
+        mLastThumbnailInfo.saveToXml(out);
         out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
         out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
         out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
@@ -1022,7 +1080,7 @@
             throws IOException, XmlPullParserException {
         Intent intent = null;
         Intent affinityIntent = null;
-        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
+        ArrayList<ActivityRecord> activities = new ArrayList<>();
         ComponentName realActivity = null;
         ComponentName origActivity = null;
         String affinity = null;
@@ -1042,6 +1100,7 @@
         int taskId = INVALID_TASK_ID;
         final int outerDepth = in.getDepth();
         TaskDescription taskDescription = new TaskDescription();
+        TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
         int taskAffiliation = INVALID_TASK_ID;
         int taskAffiliationColor = 0;
         int prevTaskId = INVALID_TASK_ID;
@@ -1090,6 +1149,8 @@
                 lastTimeOnTop = Long.valueOf(attrValue);
             } else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
                 neverRelinquishIdentity = Boolean.valueOf(attrValue);
+            } else if (attrName.startsWith(TaskThumbnailInfo.ATTR_TASK_THUMBNAILINFO_PREFIX)) {
+                thumbnailInfo.restoreFromXml(attrName, attrValue);
             } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
                 taskDescription.restoreFromXml(attrName, attrValue);
             } else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
@@ -1168,8 +1229,8 @@
                 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
                 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
                 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
-                taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
-                callingUid, callingPackage, resizeable, privileged);
+                taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
+                taskAffiliationColor, callingUid, callingPackage, resizeable, privileged);
         task.updateOverrideConfiguration(bounds);
 
         for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
@@ -1221,6 +1282,31 @@
         return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
     }
 
+    /** Updates the task's bounds and override configuration to match what is expected for the
+     * input stack. */
+    void updateOverrideConfigurationForStack(ActivityStack inStack) {
+        if (stack != null && stack == inStack) {
+            return;
+        }
+
+        if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+            if (!mResizeable) {
+                throw new IllegalArgumentException("Can not position non-resizeable task="
+                        + this + " in stack=" + inStack);
+            }
+            if (mBounds != null) {
+                return;
+            }
+            if (mLastNonFullscreenBounds != null) {
+                updateOverrideConfiguration(mLastNonFullscreenBounds);
+            } else {
+                inStack.layoutTaskInStack(this, null);
+            }
+        } else {
+            updateOverrideConfiguration(inStack.mBounds);
+        }
+    }
+
     /**
      * Returns the correct stack to use based on task type and currently set bounds,
      * regardless of the focused stack and current stack association of the task.
@@ -1354,6 +1440,8 @@
             sb.append(stringName);
             sb.append(" U=");
             sb.append(userId);
+            sb.append(" StackId=");
+            sb.append(stack != null ? stack.mStackId : INVALID_STACK_ID);
             sb.append(" sz=");
             sb.append(mActivities.size());
             sb.append('}');
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 4085489..d6fced6 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -18,7 +18,6 @@
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
-
 import static android.app.ActivityManager.USER_OP_IS_CURRENT;
 import static android.app.ActivityManager.USER_OP_SUCCESS;
 import static android.os.Process.SYSTEM_UID;
@@ -57,8 +56,11 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
@@ -134,7 +136,9 @@
         mService = service;
         mHandler = mService.mHandler;
         // User 0 is the first and only user that runs at boot.
-        mStartedUsers.put(UserHandle.USER_SYSTEM, new UserState(UserHandle.SYSTEM, true));
+        final UserState uss = new UserState(UserHandle.SYSTEM);
+        mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
+        updateUserUnlockedState(uss);
         mUserLru.add(UserHandle.USER_SYSTEM);
         updateStartedUserArrayLocked();
     }
@@ -409,6 +413,21 @@
         return userManager;
     }
 
+    private void updateUserUnlockedState(UserState uss) {
+        final IMountService mountService = IMountService.Stub
+                .asInterface(ServiceManager.getService(Context.STORAGE_SERVICE));
+        if (mountService != null) {
+            try {
+                uss.unlocked = mountService.isUserKeyUnlocked(uss.mHandle.getIdentifier());
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+        } else {
+            // System isn't fully booted yet, so guess based on property
+            uss.unlocked = !SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false);
+        }
+    }
+
     boolean startUser(final int userId, final boolean foreground) {
         if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -453,11 +472,14 @@
                 // If the user we are switching to is not currently started, then
                 // we need to start it now.
                 if (mStartedUsers.get(userId) == null) {
-                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
+                    mStartedUsers.put(userId, new UserState(new UserHandle(userId)));
                     updateStartedUserArrayLocked();
                     needStart = true;
                 }
 
+                final UserState uss = mStartedUsers.get(userId);
+                updateUserUnlockedState(uss);
+
                 final Integer userIdInt = userId;
                 mUserLru.remove(userIdInt);
                 mUserLru.add(userIdInt);
@@ -479,8 +501,6 @@
                     mUserLru.add(currentUserIdInt);
                 }
 
-                final UserState uss = mStartedUsers.get(userId);
-
                 // Make sure user is in the started state.  If it is currently
                 // stopping, we need to knock that off.
                 if (uss.mState == UserState.STATE_STOPPING) {
@@ -947,14 +967,21 @@
         return mStartedUserArray;
     }
 
-    boolean isUserRunningLocked(int userId, boolean orStopped) {
+    boolean isUserRunningLocked(int userId, int flags) {
         UserState state = getStartedUserStateLocked(userId);
         if (state == null) {
             return false;
         }
-        if (orStopped) {
+        if ((flags & ActivityManager.FLAG_OR_STOPPED) != 0) {
             return true;
         }
+        if ((flags & ActivityManager.FLAG_WITH_AMNESIA) != 0) {
+            // If user is currently locked, we fall through to default "running"
+            // behavior below
+            if (state.unlocked) {
+                return false;
+            }
+        }
         return state.mState != UserState.STATE_STOPPING
                 && state.mState != UserState.STATE_SHUTDOWN;
     }
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index b3d82bc..b5b5c1d 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -40,6 +40,7 @@
     public int mState = STATE_BOOTING;
     public boolean switching;
     public boolean initializing;
+    public boolean unlocked;
 
     /**
      * The last time that a provider was reported to usage stats as being brought to important
@@ -47,7 +48,7 @@
      */
     public final ArrayMap<String,Long> mProviderLastReportedFg = new ArrayMap<>();
 
-    public UserState(UserHandle handle, boolean initial) {
+    public UserState(UserHandle handle) {
         mHandle = handle;
     }
 
@@ -62,6 +63,11 @@
         }
         if (switching) pw.print(" SWITCHING");
         if (initializing) pw.print(" INITIALIZING");
+        if (unlocked) {
+            pw.print(" UNLOCKED");
+        } else {
+            pw.print(" LOCKED");
+        }
         pw.println();
     }
 }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d89f47c..fe9fe50 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -76,6 +76,7 @@
 import android.media.audiopolicy.IAudioPolicyCallback;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
@@ -88,6 +89,8 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManagerInternal;
+import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.System;
@@ -397,6 +400,12 @@
     // Broadcast receiver for device connections intent broadcasts
     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
 
+    /** Interface for UserManagerService. */
+    private final UserManagerInternal mUserManagerInternal;
+
+    private final UserRestrictionsListener mUserRestrictionsListener =
+            new AudioServiceUserRestrictionsListener();
+
     // Devices currently connected
     // Use makeDeviceListKey() to make a unique key for this list.
     private class DeviceListSpec {
@@ -598,6 +607,8 @@
 
         mPlatformType = AudioSystem.getPlatformType(context);
 
+        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
+
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
 
@@ -694,6 +705,8 @@
         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
 
         LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
+
+        mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
     }
 
     public void systemReady() {
@@ -1039,17 +1052,33 @@
                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
                 UserHandle.USER_CURRENT);
 
-        boolean masterMute = System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
-                0, UserHandle.USER_CURRENT) == 1;
+        final int currentUser = getCurrentUserId();
+
+        // In addition to checking the system setting, also check the current user restriction.
+        // Because of the delay before persisting VOLUME_MASTER_MUTE, there's a window where
+        // DISALLOW_ADJUST_VOLUME will be ignored when it's set right before switching users.
+        boolean masterMute = (System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
+                0, UserHandle.USER_CURRENT) == 1)
+                || mUserManagerInternal.getUserRestriction(
+                    currentUser, UserManager.DISALLOW_ADJUST_VOLUME);
         if (mUseFixedVolume) {
             masterMute = false;
             AudioSystem.setMasterVolume(1.0f);
         }
+        if (DEBUG_VOL) {
+            Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
+        }
+        setSystemAudioMute(masterMute);
         AudioSystem.setMasterMute(masterMute);
         broadcastMasterMuteStatus(masterMute);
 
         boolean microphoneMute =
-                System.getIntForUser(cr, System.MICROPHONE_MUTE, 0, UserHandle.USER_CURRENT) == 1;
+                (System.getIntForUser(cr, System.MICROPHONE_MUTE, 0, UserHandle.USER_CURRENT) == 1)
+                || mUserManagerInternal.getUserRestriction(
+                        currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
+        if (DEBUG_VOL) {
+            Log.d(TAG, String.format("Mic mute %s, user=%d", microphoneMute, currentUser));
+        }
         AudioSystem.muteMicrophone(microphoneMute);
 
         // Each stream will read its own persisted settings
@@ -1767,6 +1796,16 @@
                 != PackageManager.PERMISSION_GRANTED) {
             return;
         }
+        setMasterMuteInternalNoCallerCheck(mute, flags, userId);
+    }
+
+    private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
+        if (DEBUG_VOL) {
+            Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
+        }
+        if (mUseFixedVolume) {
+            return; // If using fixed volume, we don't mute.
+        }
         if (getCurrentUserId() == userId) {
             if (mute != AudioSystem.getMasterMute()) {
                 setSystemAudioMute(mute);
@@ -1841,7 +1880,8 @@
         return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
     }
 
-    /** @see AudioManager#setMicrophoneMute(boolean, int) */
+    /** @see AudioManager#setMicrophoneMute(boolean) */
+    @Override
     public void setMicrophoneMute(boolean on, String callingPackage, int userId) {
         // If we are being called by the system check for user we are going to change
         // so we handle user restrictions correctly.
@@ -1863,7 +1903,13 @@
                 != PackageManager.PERMISSION_GRANTED) {
             return;
         }
+        setMicrophoneMuteNoCallerCheck(on, userId);
+    }
 
+    private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) {
+        if (DEBUG_VOL) {
+            Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId));
+        }
         // If mute is for current user actually mute, else just persist the setting
         // which will be loaded on user switch.
         if (getCurrentUserId() == userId) {
@@ -5116,6 +5162,35 @@
         }
     } // end class AudioServiceBroadcastReceiver
 
+    private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
+
+        @Override
+        public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
+                Bundle prevRestrictions) {
+            // Update mic mute state.
+            {
+                final boolean wasRestricted =
+                        prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
+                final boolean isRestricted =
+                        newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
+                if (wasRestricted != isRestricted) {
+                    setMicrophoneMuteNoCallerCheck(isRestricted, userId);
+                }
+            }
+
+            // Update speaker mute state.
+            {
+                final boolean wasRestricted =
+                        prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME);
+                final boolean isRestricted =
+                        newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME);
+                if (wasRestricted != isRestricted) {
+                    setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
+                }
+            }
+        }
+    } // end class AudioServiceUserRestrictionsListener
+
     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
         PackageManager pm = mContext.getPackageManager();
         // Find the home activity of the user. It should not be killed to avoid expensive restart,
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index c1aaf07..6687412 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1353,18 +1353,9 @@
                     if (iface != null) {
                         String[] dnsServers = mDefaultDnsServers;
                         Collection<InetAddress> dnses = linkProperties.getDnsServers();
-                        if (dnses != null) {
-                            // we currently only handle IPv4
-                            ArrayList<InetAddress> v4Dnses =
-                                    new ArrayList<InetAddress>(dnses.size());
-                            for (InetAddress dnsAddress : dnses) {
-                                if (dnsAddress instanceof Inet4Address) {
-                                    v4Dnses.add(dnsAddress);
-                                }
-                            }
-                            if (v4Dnses.size() > 0) {
-                                dnsServers = NetworkUtils.makeStrings(v4Dnses);
-                            }
+                        if (dnses != null && !dnses.isEmpty()) {
+                            // TODO: remove this invocation of NetworkUtils.makeStrings().
+                            dnsServers = NetworkUtils.makeStrings(dnses);
                         }
                         try {
                             Network network = getConnectivityManager().getNetworkForType(upType);
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 82e0eaf..e2a0f82 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -84,6 +84,8 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.DeviceIdleController;
+import com.android.server.LocalServices;
 import com.android.server.accounts.AccountManagerService;
 import com.android.server.content.SyncStorageEngine.AuthorityInfo;
 import com.android.server.content.SyncStorageEngine.EndPoint;
@@ -207,6 +209,7 @@
     volatile private boolean mDataConnectionIsConnected = false;
     volatile private boolean mStorageIsLow = false;
     volatile private boolean mDeviceIsIdle = false;
+    volatile private boolean mReportedSyncActive = false;
 
     private final NotificationManager mNotificationMgr;
     private AlarmManager mAlarmService = null;
@@ -267,6 +270,12 @@
                         SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
                         null /* any sync */);
             } else {
+                if (mLocalDeviceIdleController != null) {
+                    if (!mReportedSyncActive) {
+                        mReportedSyncActive = true;
+                        mLocalDeviceIdleController.setSyncActive(true);
+                    }
+                }
                 sendCheckAlarmsMessage();
             }
         }
@@ -292,6 +301,7 @@
     };
 
     private final PowerManager mPowerManager;
+    DeviceIdleController.LocalService mLocalDeviceIdleController;
 
     // Use this as a random offset to seed all periodic syncs.
     private int mSyncRandomOffsetMillis;
@@ -1470,6 +1480,7 @@
         }
         pw.print("memory low: "); pw.println(mStorageIsLow);
         pw.print("device idle: "); pw.println(mDeviceIsIdle);
+        pw.print("reported active: "); pw.println(mReportedSyncActive);
 
         final AccountAndUser[] accounts = AccountManagerService.getSingleton().getAllAccounts();
 
@@ -2544,6 +2555,7 @@
                 if (isLoggable) {
                     Log.v(TAG, "maybeStartNextSync: no data connection, skipping");
                 }
+                setSyncActive(false);
                 return Long.MAX_VALUE;
             }
 
@@ -2551,6 +2563,7 @@
                 if (isLoggable) {
                     Log.v(TAG, "maybeStartNextSync: memory low, skipping");
                 }
+                setSyncActive(false);
                 return Long.MAX_VALUE;
             }
 
@@ -2558,6 +2571,7 @@
                 if (isLoggable) {
                     Log.v(TAG, "maybeStartNextSync: device idle, skipping");
                 }
+                setSyncActive(false);
                 return Long.MAX_VALUE;
             }
 
@@ -2567,6 +2581,7 @@
                 if (isLoggable) {
                     Log.v(TAG, "maybeStartNextSync: accounts not known, skipping");
                 }
+                setSyncActive(false);
                 return Long.MAX_VALUE;
             }
 
@@ -2772,9 +2787,25 @@
                 dispatchSyncOperation(candidate);
             }
 
+            setSyncActive(mActiveSyncContexts.size() > 0);
+
             return nextReadyToRunTime;
         }
 
+        void setSyncActive(boolean active) {
+            if (mLocalDeviceIdleController == null) {
+                mLocalDeviceIdleController
+                        = LocalServices.getService(DeviceIdleController.LocalService.class);
+            }
+            if (mLocalDeviceIdleController != null) {
+                if (mReportedSyncActive != active) {
+                    mReportedSyncActive = active;
+                    mLocalDeviceIdleController.setSyncActive(active);
+                }
+            }
+
+        }
+
         private boolean isSyncNotUsingNetworkH(ActiveSyncContext activeSyncContext) {
             final long bytesTransferredCurrent =
                     getTotalBytesTransferredByUid(activeSyncContext.mSyncAdapterUid);
diff --git a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
index 3dd1522..b52ab76 100644
--- a/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
+++ b/services/core/java/com/android/server/hdmi/DevicePowerStatusAction.java
@@ -23,6 +23,9 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Feature action that queries the power status of other device. This action is initiated via
  * {@link HdmiPlaybackClient#queryDisplayStatus(DisplayStatusCallback)} from the Android system
@@ -37,7 +40,7 @@
     private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
 
     private final int mTargetAddress;
-    private final IHdmiControlCallback mCallback;
+    private final List<IHdmiControlCallback> mCallbacks = new ArrayList<>();
 
     static DevicePowerStatusAction create(HdmiCecLocalDevice source,
             int targetAddress, IHdmiControlCallback callback) {
@@ -52,7 +55,7 @@
             int targetAddress, IHdmiControlCallback callback) {
         super(localDevice);
         mTargetAddress = targetAddress;
-        mCallback = callback;
+        addCallback(callback);
     }
 
     @Override
@@ -95,9 +98,15 @@
         }
     }
 
+    public void addCallback(IHdmiControlCallback callback) {
+        mCallbacks.add(callback);
+    }
+
     private void invokeCallback(int result) {
         try {
-            mCallback.onComplete(result);
+            for (IHdmiControlCallback callback : mCallbacks) {
+                callback.onComplete(result);
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "Callback failed:" + e);
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 3c35f5e..39c6732 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -35,6 +35,8 @@
 import java.util.List;
 import java.util.Locale;
 
+import java.util.List;
+
 /**
  * Represent a logical device of type Playback residing in Android system.
  */
@@ -97,14 +99,12 @@
     @ServiceThreadOnly
     void oneTouchPlay(IHdmiControlCallback callback) {
         assertRunOnServiceThread();
-        if (hasAction(OneTouchPlayAction.class)) {
-            Slog.w(TAG, "oneTouchPlay already in progress");
-            invokeCallback(callback, HdmiControlManager.RESULT_ALREADY_IN_PROGRESS);
+        List<OneTouchPlayAction> actions = getActions(OneTouchPlayAction.class);
+        if (!actions.isEmpty()) {
+            Slog.i(TAG, "oneTouchPlay already in progress");
+            actions.get(0).addCallback(callback);
             return;
         }
-
-        // TODO: Consider the case of multiple TV sets. For now we always direct the command
-        //       to the primary one.
         OneTouchPlayAction action = OneTouchPlayAction.create(this, Constants.ADDR_TV,
                 callback);
         if (action == null) {
@@ -118,13 +118,14 @@
     @ServiceThreadOnly
     void queryDisplayStatus(IHdmiControlCallback callback) {
         assertRunOnServiceThread();
-        if (hasAction(DevicePowerStatusAction.class)) {
-            Slog.w(TAG, "queryDisplayStatus already in progress");
-            invokeCallback(callback, HdmiControlManager.RESULT_ALREADY_IN_PROGRESS);
+        List<DevicePowerStatusAction> actions = getActions(DevicePowerStatusAction.class);
+        if (!actions.isEmpty()) {
+            Slog.i(TAG, "queryDisplayStatus already in progress");
+            actions.get(0).addCallback(callback);
             return;
         }
-        DevicePowerStatusAction action = DevicePowerStatusAction.create(this,
-                Constants.ADDR_TV, callback);
+        DevicePowerStatusAction action = DevicePowerStatusAction.create(this, Constants.ADDR_TV,
+                callback);
         if (action == null) {
             Slog.w(TAG, "Cannot initiate queryDisplayStatus");
             invokeCallback(callback, HdmiControlManager.RESULT_EXCEPTION);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index cb56b35..cd8484f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -732,6 +732,14 @@
     @ServiceThreadOnly
     protected boolean handleTextViewOn(HdmiCecMessage message) {
         assertRunOnServiceThread();
+
+        // Note that <Text View On> (and <Image View On>) command won't be handled here in
+        // most cases. A dedicated microcontroller should be in charge while Android system
+        // is in sleep mode, and the command need not be passed up to this service.
+        // The only situation where the command reaches this handler is that sleep mode is
+        // implemented in such a way that Android system is not really put to standby mode
+        // but only the display is set to blank. Then the command leads to the effect of
+        // turning on the display by the invocation of PowerManager.wakeUp().
         if (mService.isPowerStandbyOrTransient() && mAutoWakeup) {
             mService.wakeUp();
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index fe50666..8c00be5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -140,7 +140,7 @@
         // Allow unregistered source for all vendor specific commands, because we don't know
         // how to use the commands at this moment.
         addValidationInfo(Constants.MESSAGE_VENDOR_COMMAND,
-                maxLengthValidator, DEST_DIRECT | SRC_UNREGISTERED);
+                new VariableLengthValidator(1, 14), DEST_DIRECT | SRC_UNREGISTERED);
         addValidationInfo(Constants.MESSAGE_VENDOR_COMMAND_WITH_ID,
                 new VariableLengthValidator(4, 14), DEST_ALL | SRC_UNREGISTERED);
         addValidationInfo(Constants.MESSAGE_VENDOR_REMOTE_BUTTON_DOWN,
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index a711102..5c66316 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -21,6 +21,9 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Feature action that performs one touch play against TV/Display device. This action is initiated
  * via {@link android.hardware.hdmi.HdmiPlaybackClient#oneTouchPlay(OneTouchPlayCallback)} from the
@@ -47,7 +50,7 @@
     private static final int LOOP_COUNTER_MAX = 10;
 
     private final int mTargetAddress;
-    private final IHdmiControlCallback mCallback;
+    private final List<IHdmiControlCallback> mCallbacks = new ArrayList<>();
 
     private int mPowerStatusCounter = 0;
 
@@ -66,7 +69,7 @@
             IHdmiControlCallback callback) {
         super(localDevice);
         mTargetAddress = targetAddress;
-        mCallback = callback;
+        addCallback(callback);
     }
 
     @Override
@@ -125,9 +128,15 @@
         }
     }
 
+    public void addCallback(IHdmiControlCallback callback) {
+        mCallbacks.add(callback);
+    }
+
     private void invokeCallback(int result) {
         try {
-            mCallback.onComplete(result);
+            for (IHdmiControlCallback callback : mCallbacks) {
+                callback.onComplete(result);
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "Callback failed:" + e);
         }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 2b535b9..759199c 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -51,6 +51,8 @@
 import android.util.SparseArray;
 
 import com.android.internal.app.IBatteryStats;
+import com.android.server.DeviceIdleController;
+import com.android.server.LocalServices;
 import com.android.server.job.controllers.AppIdleController;
 import com.android.server.job.controllers.BatteryController;
 import com.android.server.job.controllers.ConnectivityController;
@@ -127,6 +129,7 @@
 
     IBatteryStats mBatteryStats;
     PowerManager mPowerManager;
+    DeviceIdleController.LocalService mLocalDeviceIdleController;
 
     /**
      * Set to true once we are allowed to run third party apps.
@@ -139,6 +142,11 @@
     boolean mDeviceIdleMode;
 
     /**
+     * What we last reported to DeviceIdleController about wheter we are active.
+     */
+    boolean mReportedActive;
+
+    /**
      * Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we
      * still clean up. On reinstall the package will have a new uid.
      */
@@ -268,6 +276,7 @@
             mPendingJobs.remove(cancelled);
             // Cancel if running.
             stopJobOnServiceContextLocked(cancelled);
+            reportActive();
         }
     }
 
@@ -299,12 +308,39 @@
                     }
                 } else {
                     // When coming out of idle, allow thing to start back up.
+                    if (rocking) {
+                        if (mLocalDeviceIdleController != null) {
+                            if (!mReportedActive) {
+                                mReportedActive = true;
+                                mLocalDeviceIdleController.setJobsActive(true);
+                            }
+                        }
+                    }
                     mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
                 }
             }
         }
     }
 
+    void reportActive() {
+        boolean active = false;
+        if (mPendingJobs.size() <= 0) {
+            for (int i=0; i<mActiveServices.size(); i++) {
+                JobServiceContext jsc = mActiveServices.get(i);
+                if (!jsc.isAvailable()) {
+                    active = true;
+                    break;
+                }
+            }
+        }
+        if (mLocalDeviceIdleController != null) {
+            if (mReportedActive != active) {
+                mReportedActive = active;
+                mLocalDeviceIdleController.setJobsActive(active);
+            }
+        }
+    }
+
     /**
      * Initializes the system service.
      * <p>
@@ -354,6 +390,8 @@
                 mReadyToRock = true;
                 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                         BatteryStats.SERVICE_NAME));
+                mLocalDeviceIdleController
+                        = LocalServices.getService(DeviceIdleController.LocalService.class);
                 // Create the "runners".
                 for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
                     mActiveServices.add(
@@ -623,6 +661,7 @@
                     stopJobOnServiceContextLocked(job);
                 }
             }
+            reportActive();
             if (DEBUG) {
                 final int queuedJobs = mPendingJobs.size();
                 if (queuedJobs == 0) {
@@ -685,6 +724,7 @@
                     Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Not running anything.");
                 }
             }
+            reportActive();
             if (DEBUG) {
                 Slog.d(TAG, "idle=" + idleCount + " connectivity=" +
                 connectivityCount + " charging=" + chargingCount + " tot=" +
@@ -766,6 +806,7 @@
                         it.remove();
                     }
                 }
+                reportActive();
             }
         }
     }
@@ -948,6 +989,7 @@
             pw.println();
             pw.print("mReadyToRock="); pw.println(mReadyToRock);
             pw.print("mDeviceIdleMode="); pw.println(mDeviceIdleMode);
+            pw.print("mReportedActive="); pw.println(mReportedActive);
         }
         pw.println();
     }
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 7028fa6..90dd10ea 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -948,8 +948,8 @@
                 // Launch the last PendingIntent we had with priority
                 int userId = ActivityManager.getCurrentUser();
                 UserRecord user = mUserRecords.get(userId);
-                if (user.mLastMediaButtonReceiver != null
-                        || user.mRestoredMediaButtonReceiver != null) {
+                if (user != null && (user.mLastMediaButtonReceiver != null
+                        || user.mRestoredMediaButtonReceiver != null)) {
                     if (DEBUG) {
                         Log.d(TAG, "Sending media key to last known PendingIntent "
                                 + user.mLastMediaButtonReceiver + " or restored Intent "
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 9db6a06..5b1cedc 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -239,9 +239,7 @@
             throw new RuntimeException("Problem setting firewall rules", e);
         }
 
-        synchronized (mStateLock) {
-            handleStateChangedLocked();
-        }
+        handleStateChangedLocked();
     }
 
     public void shutdown() {
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 7b1ac5ca..af20679 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.TimeUnit;
 
 /**
  * {@hide}
@@ -55,6 +56,7 @@
                 .setRequiresDeviceIdle(true)
                 .setRequiresCharging(true)
                 .setMinimumLatency(minLatency)
+                .setPeriodic(TimeUnit.DAYS.toMillis(1))
                 .build();
         js.schedule(job);
     }
@@ -89,7 +91,7 @@
                         // skip previously failing package
                         continue;
                     }
-                    if (!pm.performDexOpt(pkg, null /* instruction set */, true)) {
+                    if (!pm.performDexOpt(pkg, null /* instruction set */)) {
                         // 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/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 8abc8fc..e4dbf65 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -20,6 +20,7 @@
 import android.app.DownloadManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal.PackagesProvider;
@@ -608,7 +609,6 @@
         }
     }
 
-
     private void grantDefaultPermissionsToDefaultSystemSmsAppLPr(
             PackageParser.Package smsPackage, int userId) {
         if (doesPackageSupportRuntimePermissions(smsPackage)) {
@@ -618,7 +618,6 @@
         }
     }
 
-
     public void grantDefaultPermissionsToDefaultSmsAppLPr(String packageName, int userId) {
         Log.i(TAG, "Granting permissions to default sms app for user:" + userId);
         if (packageName == null) {
@@ -696,29 +695,23 @@
 
     private PackageParser.Package getDefaultSystemHandlerActivityPackageLPr(
             Intent intent, int userId) {
-        List<ResolveInfo> handlers = mService.mActivities.queryIntent(intent,
-                intent.resolveType(mService.mContext.getContentResolver()),
-                PackageManager.GET_DISABLED_COMPONENTS, userId);
-        if (handlers == null) {
+        ResolveInfo handler = mService.resolveIntent(intent,
+                intent.resolveType(mService.mContext.getContentResolver()), 0, userId);
+        if (handler == null || handler.activityInfo == null) {
             return null;
         }
-        final int handlerCount = handlers.size();
-        for (int i = 0; i < handlerCount; i++) {
-            ResolveInfo handler = handlers.get(i);
-            PackageParser.Package handlerPackage = getSystemPackageLPr(
-                    handler.activityInfo.packageName);
-            if (handlerPackage != null) {
-                return handlerPackage;
-            }
+        ActivityInfo activityInfo = handler.activityInfo;
+        if (activityInfo.packageName.equals(mService.mResolveActivity.packageName)
+                && activityInfo.name.equals(mService.mResolveActivity.name)) {
+            return null;
         }
-        return null;
+        return getSystemPackageLPr(handler.activityInfo.packageName);
     }
 
     private PackageParser.Package getDefaultSystemHandlerServicePackageLPr(
             Intent intent, int userId) {
         List<ResolveInfo> handlers = mService.queryIntentServices(intent,
-                intent.resolveType(mService.mContext.getContentResolver()),
-                PackageManager.GET_DISABLED_COMPONENTS, userId);
+                intent.resolveType(mService.mContext.getContentResolver()), 0, userId);
         if (handlers == null) {
             return null;
         }
@@ -744,10 +737,9 @@
         for (String syncAdapterPackageName : syncAdapterPackageNames) {
             homeIntent.setPackage(syncAdapterPackageName);
 
-            List<ResolveInfo> homeActivities = mService.mActivities.queryIntent(homeIntent,
-                    homeIntent.resolveType(mService.mContext.getContentResolver()),
-                    PackageManager.GET_DISABLED_COMPONENTS, userId);
-            if (!homeActivities.isEmpty()) {
+            ResolveInfo homeActivity = mService.resolveIntent(homeIntent,
+                    homeIntent.resolveType(mService.mContext.getContentResolver()), 0, userId);
+            if (homeActivity != null) {
                 continue;
             }
 
@@ -842,8 +834,8 @@
 
                     mService.grantRuntimePermission(pkg.packageName, permission, userId);
                     if (DEBUG) {
-                        Log.i(TAG, "Granted " + permission + " to default handler "
-                                + pkg.packageName);
+                        Log.i(TAG, "Granted " + (systemFixed ? "fixed " : "not fixed ")
+                                + permission + " to default handler " + pkg.packageName);
                     }
 
                     int newFlags = PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
@@ -854,6 +846,19 @@
                     mService.updatePermissionFlags(permission, pkg.packageName,
                             newFlags, newFlags, userId);
                 }
+
+                // If a component gets a permission for being the default handler A
+                // and also default handler B, we grant the weaker grant form.
+                if ((flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
+                        && (flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
+                        && !systemFixed) {
+                    if (DEBUG) {
+                        Log.i(TAG, "Granted not fixed " + permission + " to default handler "
+                                + pkg.packageName);
+                    }
+                    mService.updatePermissionFlags(permission, pkg.packageName,
+                            PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, 0, userId);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 150c849..99a051a 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -185,15 +185,6 @@
         return mInstaller.execute(builder.toString());
     }
 
-    public int rename(String oldname, String newname) {
-        StringBuilder builder = new StringBuilder("rename");
-        builder.append(' ');
-        builder.append(oldname);
-        builder.append(' ');
-        builder.append(newname);
-        return mInstaller.execute(builder.toString());
-    }
-
     @Deprecated
     public int fixUid(String name, int uid, int gid) {
         return fixUid(null, name, uid, gid);
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 56c4fb1..d29a623 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -55,7 +55,6 @@
     static final int DEX_OPT_FAILED = -1;
 
     private final PackageManagerService mPackageManagerService;
-    private ArraySet<PackageParser.Package> mDeferredDexOpt;
 
     private final PowerManager.WakeLock mDexoptWakeLock;
     private volatile boolean mSystemReady;
@@ -75,8 +74,7 @@
      * {@link PackageManagerService#mInstallLock}.
      */
     int performDexOpt(PackageParser.Package pkg, String[] instructionSets,
-            boolean forceDex, boolean defer, boolean inclDependencies,
-            boolean bootComplete, boolean useJit) {
+            boolean inclDependencies) {
         ArraySet<String> done;
         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
             done = new ArraySet<String>();
@@ -91,8 +89,7 @@
                 mDexoptWakeLock.acquire();
             }
             try {
-                return performDexOptLI(pkg, instructionSets, forceDex, defer, bootComplete,
-                        useJit, done);
+                return performDexOptLI(pkg, instructionSets, done);
             } finally {
                 if (useLock) {
                     mDexoptWakeLock.release();
@@ -102,7 +99,6 @@
     }
 
     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
-            boolean forceDex, boolean defer, boolean bootComplete, boolean useJit,
             ArraySet<String> done) {
         final String[] instructionSets = targetInstructionSets != null ?
                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
@@ -110,12 +106,10 @@
         if (done != null) {
             done.add(pkg.packageName);
             if (pkg.usesLibraries != null) {
-                performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer,
-                        bootComplete, useJit, done);
+                performDexOptLibsLI(pkg.usesLibraries, instructionSets, done);
             }
             if (pkg.usesOptionalLibraries != null) {
-                performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer,
-                        bootComplete, useJit, done);
+                performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, done);
             }
         }
 
@@ -134,30 +128,18 @@
         // 3.) we are skipping an unneeded dexopt
         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
-            if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
+            if (pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
                 continue;
             }
 
             for (String path : paths) {
                 final int dexoptNeeded;
-                if (forceDex) {
-                    dexoptNeeded = DexFile.DEX2OAT_NEEDED;
-                } else {
-                    try {
-                        dexoptNeeded = DexFile.getDexOptNeeded(path, pkg.packageName,
-                                dexCodeInstructionSet, defer);
-                    } catch (IOException ioe) {
-                        Slog.w(TAG, "IOException reading apk: " + path, ioe);
-                        return DEX_OPT_FAILED;
-                    }
-                }
-
-                if (!forceDex && defer && dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
-                    // We're deciding to defer a needed dexopt. Don't bother dexopting for other
-                    // paths and instruction sets. We'll deal with them all together when we process
-                    // our list of deferred dexopts.
-                    addPackageForDeferredDexopt(pkg);
-                    return DEX_OPT_DEFERRED;
+                try {
+                    dexoptNeeded = DexFile.getDexOptNeeded(path, pkg.packageName,
+                            dexCodeInstructionSet, /* defer */false);
+                } catch (IOException ioe) {
+                    Slog.w(TAG, "IOException reading apk: " + path, ioe);
+                    return DEX_OPT_FAILED;
                 }
 
                 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
@@ -177,20 +159,17 @@
                     Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
                             + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
                             + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
-                            + " oatDir = " + oatDir + " bootComplete=" + bootComplete
-                            + " useJit=" + useJit);
+                            + " 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)
-                            | (bootComplete ? DEXOPT_BOOTCOMPLETE : 0)
-                            | (useJit ? DEXOPT_USEJIT : 0);
+                            | DEXOPT_BOOTCOMPLETE;
                     final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
                             pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir, dexFlags);
 
-                    // Dex2oat might fail due to compiler / verifier errors. We soldier on
-                    // regardless, and attempt to interpret the app as a safety net.
+                    // Dex2oat might fail due to compiler / verifier errors.
                     if (ret == 0) {
                         performedDexOpt = true;
                     }
@@ -243,34 +222,16 @@
     }
 
     private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
-            boolean forceDex, boolean defer, boolean bootComplete, boolean useJit,
             ArraySet<String> done) {
         for (String libName : libs) {
             PackageParser.Package libPkg = mPackageManagerService.findSharedNonSystemLibrary(
                     libName);
             if (libPkg != null && !done.contains(libName)) {
-                performDexOptLI(libPkg, instructionSets, forceDex, defer, bootComplete, useJit, done);
+                performDexOptLI(libPkg, instructionSets, done);
             }
         }
     }
 
-    /**
-     * Clears set of deferred dexopt packages.
-     * @return content of dexopt set if it was not empty
-     */
-    public ArraySet<PackageParser.Package> clearDeferredDexOptPackages() {
-        ArraySet<PackageParser.Package> result = mDeferredDexOpt;
-        mDeferredDexOpt = null;
-        return result;
-    }
-
-    public void addPackageForDeferredDexopt(PackageParser.Package pkg) {
-        if (mDeferredDexOpt == null) {
-            mDeferredDexOpt = new ArraySet<>();
-        }
-        mDeferredDexOpt.add(pkg);
-    }
-
     void systemReady() {
         mSystemReady = true;
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 08f9bd5..02a6204 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -105,6 +105,7 @@
 import android.content.ServiceConnection;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.AppsQueryHelper;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
@@ -429,8 +430,6 @@
     final Context mContext;
     final boolean mFactoryTest;
     final boolean mOnlyCore;
-    final boolean mLazyDexOpt;
-    final long mDexOptLRUThresholdInMills;
     final DisplayMetrics mMetrics;
     final int mDefParseFlags;
     final String[] mSeparateProcesses;
@@ -1415,18 +1414,18 @@
                                 }
                             }
                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
-                                    packageName, extras, null, null, firstUsers);
+                                    packageName, extras, 0, null, null, firstUsers);
                             final boolean update = res.removedInfo.removedPackage != null;
                             if (update) {
                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
                             }
                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
-                                    packageName, extras, null, null, updateUsers);
+                                    packageName, extras, 0, null, null, updateUsers);
                             if (update) {
                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
-                                        packageName, extras, null, null, updateUsers);
+                                        packageName, extras, 0, null, null, updateUsers);
                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
-                                        null, null, packageName, null, updateUsers);
+                                        null, null, 0, packageName, null, updateUsers);
 
                                 // treat asec-hosted packages like removable media on upgrade
                                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
@@ -1812,10 +1811,48 @@
             boolean factoryTest, boolean onlyCore) {
         PackageManagerService m = new PackageManagerService(context, installer,
                 factoryTest, onlyCore);
+        m.enableSystemUserApps();
         ServiceManager.addService("package", m);
         return m;
     }
 
+    private void enableSystemUserApps() {
+        if (!UserManager.isSplitSystemUser()) {
+            return;
+        }
+        // For system user, enable apps based on the following conditions:
+        // - app is whitelisted or belong to one of these groups:
+        //   -- system app which has no launcher icons
+        //   -- system app which has INTERACT_ACROSS_USERS permission
+        //   -- system IME app
+        // - app is not in the blacklist
+        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
+        Set<String> enableApps = new ArraySet<>();
+        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
+                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
+                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
+        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
+        enableApps.addAll(wlApps);
+        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
+        enableApps.removeAll(blApps);
+
+        List<String> systemApps = queryHelper.queryApps(0, /* systemAppsOnly */ true,
+                UserHandle.SYSTEM);
+        final int systemAppsSize = systemApps.size();
+        synchronized (mPackages) {
+            for (int i = 0; i < systemAppsSize; i++) {
+                String pName = systemApps.get(i);
+                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
+                // Should not happen, but we shouldn't be failing if it does
+                if (pkgSetting == null) {
+                    continue;
+                }
+                boolean installed = enableApps.contains(pName);
+                pkgSetting.setInstalled(installed, UserHandle.USER_SYSTEM);
+            }
+        }
+    }
+
     static String[] splitString(String str, char sep) {
         int count = 1;
         int i = 0;
@@ -1856,7 +1893,6 @@
         mContext = context;
         mFactoryTest = factoryTest;
         mOnlyCore = onlyCore;
-        mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
         mMetrics = new DisplayMetrics();
         mSettings = new Settings(mPackages);
         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
@@ -1872,15 +1908,6 @@
         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
 
-        // TODO: add a property to control this?
-        long dexOptLRUThresholdInMinutes;
-        if (mLazyDexOpt) {
-            dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
-        } else {
-            dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
-        }
-        mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
-
         String separateProcesses = SystemProperties.get("debug.separate_processes");
         if (separateProcesses != null && separateProcesses.length() > 0) {
             if ("*".equals(separateProcesses)) {
@@ -1929,8 +1956,7 @@
             mUserAppDataDir = new File(dataDir, "user");
             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
 
-            sUserManager = new UserManagerService(context, this,
-                    mInstallLock, mPackages);
+            sUserManager = new UserManagerService(context, this, mPackages);
 
             // Propagate permission configuration in to package manager.
             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
@@ -1975,31 +2001,14 @@
             // scanning install directories.
             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
 
-            final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
-
-            /**
-             * Add everything in the in the boot class path to the
-             * list of process files because dexopt will have been run
-             * if necessary during zygote startup.
-             */
             final String bootClassPath = System.getenv("BOOTCLASSPATH");
             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
 
-            if (bootClassPath != null) {
-                String[] bootClassPathElements = splitString(bootClassPath, ':');
-                for (String element : bootClassPathElements) {
-                    alreadyDexOpted.add(element);
-                }
-            } else {
+            if (bootClassPath == null) {
                 Slog.w(TAG, "No BOOTCLASSPATH found!");
             }
 
-            if (systemServerClassPath != null) {
-                String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
-                for (String element : systemServerClassPathElements) {
-                    alreadyDexOpted.add(element);
-                }
-            } else {
+            if (systemServerClassPath == null) {
                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
             }
 
@@ -2026,7 +2035,6 @@
                         try {
                             int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
-                                alreadyDexOpted.add(lib);
                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
                                         dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/);
                             }
@@ -2042,52 +2050,6 @@
 
             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
 
-            // Gross hack for now: we know this file doesn't contain any
-            // code, so don't dexopt it to avoid the resulting log spew.
-            alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
-
-            // Gross hack for now: we know this file is only part of
-            // the boot class path for art, so don't dexopt it to
-            // avoid the resulting log spew.
-            alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
-
-            /**
-             * There are a number of commands implemented in Java, which
-             * we currently need to do the dexopt on so that they can be
-             * run from a non-root shell.
-             */
-            String[] frameworkFiles = frameworkDir.list();
-            if (frameworkFiles != null) {
-                // TODO: We could compile these only for the most preferred ABI. We should
-                // first double check that the dex files for these commands are not referenced
-                // by other system apps.
-                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
-                    for (int i=0; i<frameworkFiles.length; i++) {
-                        File libPath = new File(frameworkDir, frameworkFiles[i]);
-                        String path = libPath.getPath();
-                        // Skip the file if we already did it.
-                        if (alreadyDexOpted.contains(path)) {
-                            continue;
-                        }
-                        // Skip the file if it is not a type we want to dexopt.
-                        if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
-                            continue;
-                        }
-                        try {
-                            int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
-                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
-                                mInstaller.dexopt(path, Process.SYSTEM_UID, dexCodeInstructionSet,
-                                        dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/);
-                            }
-                        } catch (FileNotFoundException e) {
-                            Slog.w(TAG, "Jar not found: " + path);
-                        } catch (IOException e) {
-                            Slog.w(TAG, "Exception reading jar: " + path, e);
-                        }
-                    }
-                }
-            }
-
             final VersionInfo ver = mSettings.getInternalVersion();
             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
             // when upgrading from pre-M, promote system app permissions from install to runtime
@@ -2306,7 +2268,6 @@
                 // the rest of the commands above) because there's precious little we
                 // can do about it. A settings error is reported, though.
                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
-                        false /* force dexopt */, false /* defer dexopt */,
                         false /* boot complete */);
             }
 
@@ -2951,9 +2912,8 @@
                 pkg.applicationInfo.packageName = packageName;
                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
                 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
-                pkg.applicationInfo.dataDir = Environment
-                        .getDataUserPackageDirectory(ps.volumeUuid, userId, packageName)
-                        .getAbsolutePath();
+                pkg.applicationInfo.uid = ps.appId;
+                pkg.applicationInfo.initForUser(userId);
                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
             }
@@ -3054,15 +3014,43 @@
         }
     }
 
+    /**
+     * Augment the given flags depending on current user running state. This is
+     * purposefully done before acquiring {@link #mPackages} lock.
+     */
+    private int augmentFlagsForUser(int flags, int userId) {
+        if (SystemProperties.getBoolean(StorageManager.PROP_HAS_FBE, false)) {
+            final IMountService mount = IMountService.Stub
+                    .asInterface(ServiceManager.getService(Context.STORAGE_SERVICE));
+            if (mount == null) {
+                // We must be early in boot, so the best we can do is assume the
+                // user is fully running.
+                return flags;
+            }
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!mount.isUserKeyUnlocked(userId)) {
+                    flags |= PackageManager.FLAG_USER_RUNNING_WITH_AMNESIA;
+                }
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+        return flags;
+    }
+
     @Override
     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
         synchronized (mPackages) {
             PackageParser.Activity a = mActivities.mActivities.get(component);
 
             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
-            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
+            if (a != null && mSettings.isEnabledAndVisibleLPr(a.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
@@ -3101,12 +3089,13 @@
     @Override
     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
         synchronized (mPackages) {
             PackageParser.Activity a = mReceivers.mActivities.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
                 TAG, "getReceiverInfo " + component + ": " + a);
-            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
+            if (a != null && mSettings.isEnabledAndVisibleLPr(a.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
@@ -3119,12 +3108,13 @@
     @Override
     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
         synchronized (mPackages) {
             PackageParser.Service s = mServices.mServices.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
                 TAG, "getServiceInfo " + component + ": " + s);
-            if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
+            if (s != null && mSettings.isEnabledAndVisibleLPr(s.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
@@ -3137,12 +3127,13 @@
     @Override
     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
         synchronized (mPackages) {
             PackageParser.Provider p = mProviders.mProviders.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
                 TAG, "getProviderInfo " + component + ": " + p);
-            if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
+            if (p != null && mSettings.isEnabledAndVisibleLPr(p.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
@@ -3785,12 +3776,6 @@
 
             PermissionsState permissionsState = sb.getPermissionsState();
 
-            // Only the package manager can change flags for system component permissions.
-            final int flags = permissionsState.getPermissionFlags(bp.name, userId);
-            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
-                return;
-            }
-
             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
 
             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
@@ -4240,6 +4225,7 @@
     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
             int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
         return chooseBestActivity(intent, resolvedType, flags, query, userId);
@@ -4381,10 +4367,12 @@
         return null;
     }
 
+    // TODO: handle preferred activities missing while user has amnesia
     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
             List<ResolveInfo> query, int priority, boolean always,
             boolean removeMatches, boolean debug, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         // writer
         synchronized (mPackages) {
             if (intent.getSelector() != null) {
@@ -4583,6 +4571,7 @@
     public List<ResolveInfo> queryIntentActivities(Intent intent,
             String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
+        flags = augmentFlagsForUser(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
         ComponentName comp = intent.getComponent();
         if (comp == null) {
@@ -5048,6 +5037,7 @@
             Intent[] specifics, String[] specificTypes, Intent intent,
             String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
+        flags = augmentFlagsForUser(flags, userId);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
                 false, "query intent activity options");
         final String resultsAction = intent.getAction();
@@ -5220,6 +5210,7 @@
     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
             int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
+        flags = augmentFlagsForUser(flags, userId);
         ComponentName comp = intent.getComponent();
         if (comp == null) {
             if (intent.getSelector() != null) {
@@ -5255,8 +5246,9 @@
 
     @Override
     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
-        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
+        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
         if (query != null) {
             if (query.size() >= 1) {
                 // If there is more than one service with the same priority,
@@ -5271,6 +5263,7 @@
     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
             int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
+        flags = augmentFlagsForUser(flags, userId);
         ComponentName comp = intent.getComponent();
         if (comp == null) {
             if (intent.getSelector() != null) {
@@ -5308,6 +5301,7 @@
     public List<ResolveInfo> queryIntentContentProviders(
             Intent intent, String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
+        flags = augmentFlagsForUser(flags, userId);
         ComponentName comp = intent.getComponent();
         if (comp == null) {
             if (intent.getSelector() != null) {
@@ -5424,6 +5418,7 @@
     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
             String[] permissions, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
 
         // writer
@@ -5451,6 +5446,7 @@
     @Override
     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
 
         // writer
@@ -5517,6 +5513,7 @@
     @Override
     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
         // reader
         synchronized (mPackages) {
             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
@@ -5524,7 +5521,7 @@
                     ? mSettings.mPackages.get(provider.owner.packageName)
                     : null;
             return ps != null
-                    && mSettings.isEnabledLPr(provider.info, flags, userId)
+                    && mSettings.isEnabledAndVisibleLPr(provider.info, flags, userId)
                     && (!mSafeMode || (provider.info.applicationInfo.flags
                             &ApplicationInfo.FLAG_SYSTEM) != 0)
                     ? PackageParser.generateProviderInfo(provider, flags,
@@ -5565,12 +5562,15 @@
     @Override
     public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
             int uid, int flags) {
+        final int userId = processName != null ? UserHandle.getUserId(uid)
+                : UserHandle.getCallingUserId();
+        if (!sUserManager.exists(userId)) return null;
+        flags = augmentFlagsForUser(flags, userId);
+
         ArrayList<ProviderInfo> finalList = null;
         // reader
         synchronized (mPackages) {
             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
-            final int userId = processName != null ?
-                    UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
             while (i.hasNext()) {
                 final PackageParser.Provider p = i.next();
                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
@@ -5578,7 +5578,7 @@
                         && (processName == null
                                 || (p.info.processName.equals(processName)
                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
-                        && mSettings.isEnabledLPr(p.info, flags, userId)
+                        && mSettings.isEnabledAndVisibleLPr(p.info, flags, userId)
                         && (!mSafeMode
                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
                     if (finalList == null) {
@@ -6111,8 +6111,8 @@
     }
 
     @Override
-    public void performBootDexOpt() {
-        enforceSystemOrRoot("Only the system can request dexopt be performed");
+    public void performFstrimIfNeeded() {
+        enforceSystemOrRoot("Only the system can request fstrim");
 
         // Before everything else, see whether we need to fstrim.
         try {
@@ -6153,98 +6153,6 @@
         } catch (RemoteException e) {
             // Can't happen; MountService is local
         }
-
-        final ArraySet<PackageParser.Package> pkgs;
-        synchronized (mPackages) {
-            pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages();
-        }
-
-        if (pkgs != null) {
-            // Sort apps by importance for dexopt ordering. Important apps are given more priority
-            // in case the device runs out of space.
-            ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
-            // Give priority to core apps.
-            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
-                PackageParser.Package pkg = it.next();
-                if (pkg.coreApp) {
-                    if (DEBUG_DEXOPT) {
-                        Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
-                    }
-                    sortedPkgs.add(pkg);
-                    it.remove();
-                }
-            }
-            // Give priority to system apps that listen for pre boot complete.
-            Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
-            ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM);
-            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
-                PackageParser.Package pkg = it.next();
-                if (pkgNames.contains(pkg.packageName)) {
-                    if (DEBUG_DEXOPT) {
-                        Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
-                    }
-                    sortedPkgs.add(pkg);
-                    it.remove();
-                }
-            }
-            // Filter out packages that aren't recently used.
-            filterRecentlyUsedApps(pkgs);
-            // Add all remaining apps.
-            for (PackageParser.Package pkg : pkgs) {
-                if (DEBUG_DEXOPT) {
-                    Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
-                }
-                sortedPkgs.add(pkg);
-            }
-
-            // If we want to be lazy, filter everything that wasn't recently used.
-            if (mLazyDexOpt) {
-                filterRecentlyUsedApps(sortedPkgs);
-            }
-
-            int i = 0;
-            int total = sortedPkgs.size();
-            File dataDir = Environment.getDataDirectory();
-            long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
-            if (lowThreshold == 0) {
-                throw new IllegalStateException("Invalid low memory threshold");
-            }
-            for (PackageParser.Package pkg : sortedPkgs) {
-                long usableSpace = dataDir.getUsableSpace();
-                if (usableSpace < lowThreshold) {
-                    Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
-                    break;
-                }
-                performBootDexOpt(pkg, ++i, total);
-            }
-        }
-    }
-
-    private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
-        // Filter out packages that aren't recently used.
-        //
-        // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
-        // should do a full dexopt.
-        if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
-            int total = pkgs.size();
-            int skipped = 0;
-            long now = System.currentTimeMillis();
-            for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
-                PackageParser.Package pkg = i.next();
-                long then = pkg.mLastPackageUsageTimeInMills;
-                if (then + mDexOptLRUThresholdInMills < now) {
-                    if (DEBUG_DEXOPT) {
-                        Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
-                              ((then == 0) ? "never" : new Date(then)));
-                    }
-                    i.remove();
-                    skipped++;
-                }
-            }
-            if (DEBUG_DEXOPT) {
-                Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
-            }
-        }
     }
 
     private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
@@ -6263,54 +6171,36 @@
         return pkgNames;
     }
 
-    private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
-        if (DEBUG_DEXOPT) {
-            Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
-        }
-        if (!isFirstBoot()) {
-            try {
-                ActivityManagerNative.getDefault().showBootMessage(
-                        mContext.getResources().getString(R.string.android_upgrading_apk,
-                                curr, total), true);
-            } catch (RemoteException e) {
+    @Override
+    public void notifyPackageUse(String packageName) {
+        synchronized (mPackages) {
+            PackageParser.Package p = mPackages.get(packageName);
+            if (p == null) {
+                return;
             }
-        }
-        PackageParser.Package p = pkg;
-        synchronized (mInstallLock) {
-            mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */,
-                    false /* force dex */, false /* defer */, true /* include dependencies */,
-                    false /* boot complete */, false /*useJit*/);
+            p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
         }
     }
 
     @Override
     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
-        return performDexOptTraced(packageName, instructionSet, false);
+        return performDexOptTraced(packageName, instructionSet);
     }
 
-    public boolean performDexOpt(
-            String packageName, String instructionSet, boolean backgroundDexopt) {
-        return performDexOptTraced(packageName, instructionSet, backgroundDexopt);
+    public boolean performDexOpt(String packageName, String instructionSet) {
+        return performDexOptTraced(packageName, instructionSet);
     }
 
-    private boolean performDexOptTraced(
-            String packageName, String instructionSet, boolean backgroundDexopt) {
+    private boolean performDexOptTraced(String packageName, String instructionSet) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
         try {
-            return performDexOptInternal(packageName, instructionSet, backgroundDexopt);
+            return performDexOptInternal(packageName, instructionSet);
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
     }
 
-    private boolean performDexOptInternal(
-            String packageName, String instructionSet, boolean backgroundDexopt) {
-        boolean dexopt = mLazyDexOpt || backgroundDexopt;
-        boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
-        if (!dexopt && !updateUsage) {
-            // We aren't going to dexopt or update usage, so bail early.
-            return false;
-        }
+    private boolean performDexOptInternal(String packageName, String instructionSet) {
         PackageParser.Package p;
         final String targetInstructionSet;
         synchronized (mPackages) {
@@ -6318,14 +6208,7 @@
             if (p == null) {
                 return false;
             }
-            if (updateUsage) {
-                p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
-            }
             mPackageUsage.write(false);
-            if (!dexopt) {
-                // We aren't going to dexopt, so bail early.
-                return false;
-            }
 
             targetInstructionSet = instructionSet != null ? instructionSet :
                     getPrimaryInstructionSet(p.applicationInfo);
@@ -6338,8 +6221,7 @@
             synchronized (mInstallLock) {
                 final String[] instructionSets = new String[] { targetInstructionSet };
                 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
-                        false /* forceDex */, false /* defer */, true /* inclDependencies */,
-                        true /* boot complete */, false /*useJit*/);
+                        true /* inclDependencies */);
                 return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
             }
         } finally {
@@ -6389,8 +6271,7 @@
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
 
             final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
-                    true /*forceDex*/, false /* defer */, true /* inclDependencies */,
-                    true /* boot complete */, false /*useJit*/);
+                    true /* inclDependencies */);
 
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -6950,17 +6831,10 @@
                 pkg.applicationInfo.processName,
                 pkg.applicationInfo.uid);
 
-        File dataPath;
-        if (mPlatformPackage == pkg) {
-            // The system package is special.
-            dataPath = new File(Environment.getDataDirectory(), "system");
-
-            pkg.applicationInfo.dataDir = dataPath.getPath();
-
-        } else {
+        if (pkg != mPlatformPackage) {
             // This is a normal package, need to make its data directory.
-            dataPath = Environment.getDataUserPackageDirectory(pkg.volumeUuid,
-                    UserHandle.USER_SYSTEM, pkg.packageName);
+            final File dataPath = Environment.getDataUserCredentialEncryptedPackageDirectory(
+                    pkg.volumeUuid, UserHandle.USER_SYSTEM, pkg.packageName);
 
             boolean uidError = false;
             if (dataPath.exists()) {
@@ -7049,7 +6923,7 @@
                         }
                     }
                 }
-                pkg.applicationInfo.dataDir = dataPath.getPath();
+
                 if (mShouldRestoreconData) {
                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
                     mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName,
@@ -7068,15 +6942,11 @@
                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
                             "Unable to create data dirs [errorCode=" + ret + "]");
                 }
-
-                if (dataPath.exists()) {
-                    pkg.applicationInfo.dataDir = dataPath.getPath();
-                } else {
-                    Slog.w(TAG, "Unable to create data directory: " + dataPath);
-                    pkg.applicationInfo.dataDir = null;
-                }
             }
 
+            // Get all of our default paths setup
+            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
+
             pkgSetting.uidError = uidError;
         }
 
@@ -7191,7 +7061,7 @@
                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
         }
 
-        if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
+        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
             // We don't do this here during boot because we can do it all
             // at once after scanning all existing packages.
             //
@@ -7199,21 +7069,9 @@
             // we can avoid redundant dexopts, and also to make sure we've got the
             // code and package path correct.
             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
-                    pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, true /* boot complete */);
+                    pkg, true /* boot complete */);
         }
 
-        if ((scanFlags & SCAN_NO_DEX) == 0) {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-
-            int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
-                    forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */,
-                    (scanFlags & SCAN_BOOTING) == 0, false /*useJit*/);
-
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-            if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
-                throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
-            }
-        }
         if (mFactoryTest && pkg.requestedPermissions.contains(
                 android.Manifest.permission.FACTORY_TEST)) {
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
@@ -7265,7 +7123,7 @@
                                     + name + " that is not declared on system image; skipping");
                         }
                     }
-                    if ((scanFlags&SCAN_BOOTING) == 0) {
+                    if ((scanFlags & SCAN_BOOTING) == 0) {
                         // If we are not booting, we need to update any applications
                         // that are clients of our shared library.  If we are booting,
                         // this will all be done once the scan is complete.
@@ -7275,30 +7133,6 @@
             }
         }
 
-        // We also need to dexopt any apps that are dependent on this library.  Note that
-        // if these fail, we should abort the install since installing the library will
-        // result in some apps being broken.
-        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-        try {
-            if (clientLibPkgs != null) {
-                if ((scanFlags & SCAN_NO_DEX) == 0) {
-                    for (int i = 0; i < clientLibPkgs.size(); i++) {
-                        PackageParser.Package clientPkg = clientLibPkgs.get(i);
-                        int result = mPackageDexOptimizer.performDexOpt(clientPkg,
-                                null /* instruction sets */, forceDex,
-                                (scanFlags & SCAN_DEFER_DEX) != 0, false,
-                                (scanFlags & SCAN_BOOTING) == 0, false /*useJit*/);
-                        if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
-                            throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
-                                    "scanPackageLI failed to dexopt clientLibPkgs");
-                        }
-                    }
-                }
-            }
-        } finally {
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
-
         // Request the ActivityManager to kill the process(only for existing packages)
         // so that we do not end up in a confused state while the user is still using the older
         // version of the application while the new one gets installed.
@@ -7630,6 +7464,8 @@
                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
                 a.info.dataDir = pkg.applicationInfo.dataDir;
+                a.info.deviceEncryptedDataDir = pkg.applicationInfo.deviceEncryptedDataDir;
+                a.info.credentialEncryptedDataDir = pkg.applicationInfo.credentialEncryptedDataDir;
 
                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
                 // need other information about the application, like the ABI and what not ?
@@ -7843,8 +7679,7 @@
      * adds unnecessary complexity.
      */
     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
-            PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt,
-            boolean bootComplete) {
+            PackageParser.Package scannedPackage, boolean bootComplete) {
         String requiredInstructionSet = null;
         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
             requiredInstructionSet = VMRuntime.getInstructionSet(
@@ -7906,22 +7741,8 @@
                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
-
-                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-
-                        int result = mPackageDexOptimizer.performDexOpt(ps.pkg,
-                                null /* instruction sets */, forceDexOpt, deferDexOpt, true,
-                                bootComplete, false /*useJit*/);
-
-                        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-                        if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
-                            ps.primaryCpuAbiString = null;
-                            ps.pkg.applicationInfo.primaryCpuAbi = null;
-                            return;
-                        } else {
-                            mInstaller.rmdex(ps.codePathString,
-                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
-                        }
+                        mInstaller.rmdex(ps.codePathString,
+                                getDexCodeInstructionSet(getPreferredInstructionSet()));
                     }
                 }
             }
@@ -8991,7 +8812,7 @@
         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
                 int match, int userId) {
             if (!sUserManager.exists(userId)) return null;
-            if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
+            if (!mSettings.isEnabledAndVisibleLPr(info.activity.info, mFlags, userId)) {
                 return null;
             }
             final PackageParser.Activity activity = info.activity;
@@ -9215,7 +9036,7 @@
                 int match, int userId) {
             if (!sUserManager.exists(userId)) return null;
             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
-            if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
+            if (!mSettings.isEnabledAndVisibleLPr(info.service.info, mFlags, userId)) {
                 return null;
             }
             final PackageParser.Service service = info.service;
@@ -9438,7 +9259,7 @@
             if (!sUserManager.exists(userId))
                 return null;
             final PackageParser.ProviderIntentInfo info = filter;
-            if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
+            if (!mSettings.isEnabledAndVisibleLPr(info.provider.info, mFlags, userId)) {
                 return null;
             }
             final PackageParser.Provider provider = info.provider;
@@ -9549,8 +9370,8 @@
         }
     };
 
-    final void sendPackageBroadcast(final String action, final String pkg,
-            final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver,
+    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
+            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
             final int[] userIds) {
         mHandler.post(new Runnable() {
             @Override
@@ -9580,7 +9401,7 @@
                             intent.putExtra(Intent.EXTRA_UID, uid);
                         }
                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
-                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
                         if (DEBUG_BROADCASTS) {
                             RuntimeException here = new RuntimeException("here");
                             here.fillInStackTrace();
@@ -9772,12 +9593,12 @@
         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
 
         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
-                packageName, extras, null, null, new int[] {userId});
+                packageName, extras, 0, null, null, new int[] {userId});
         try {
             IActivityManager am = ActivityManagerNative.getDefault();
             final boolean isSystem =
                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
-            if (isSystem && am.isUserRunning(userId, false)) {
+            if (isSystem && am.isUserRunning(userId, 0)) {
                 // The just-installed/enabled app is bundled on the system, so presumed
                 // to be able to run automatically without needing an explicit launch.
                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
@@ -12691,19 +12512,6 @@
                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
                 return;
             }
-
-            // Run dexopt before old package gets removed, to minimize time when app is unavailable
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-
-            int result = mPackageDexOptimizer
-                    .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */,
-                            false /* defer */, false /* inclDependencies */,
-                            true /*bootComplete*/, quickInstall /*useJit*/);
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-            if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
-                res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
-                return;
-            }
         }
 
         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
@@ -13000,8 +12808,14 @@
                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
         try {
             if (dpm != null) {
+                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwner();
+                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
+                        : deviceOwnerComponentName.getPackageName();
                 // Does the package contains the device owner?
-                if (dpm.isDeviceOwnerPackage(packageName)) {
+                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
+                // this check is probably not needed, since DO should be registered as a device
+                // admin on some user too. (Original bug for this: b/17657954)
+                if (packageName.equals(deviceOwnerPackageName)) {
                     return true;
                 }
                 // Does it contain a device admin for any user?
@@ -13089,11 +12903,11 @@
                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
 
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
-                        extras, null, null, null);
+                        extras, 0, null, null, null);
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
-                        extras, null, null, null);
+                        extras, 0, null, null, null);
                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
-                        null, packageName, null, null);
+                        null, 0, packageName, null, null);
             }
         }
         // Force a gc here.
@@ -13128,14 +12942,14 @@
             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
             if (removedPackage != null) {
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
-                        extras, null, null, removedUsers);
+                        extras, 0, null, null, removedUsers);
                 if (fullRemove && !replacing) {
                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
-                            extras, null, null, removedUsers);
+                            extras, 0, null, null, removedUsers);
                 }
             }
             if (removedAppId >= 0) {
-                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
+                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
                         removedUsers);
             }
         }
@@ -14835,7 +14649,12 @@
         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
         extras.putInt(Intent.EXTRA_UID, packageUid);
-        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
+        // If this is not reporting a change of the overall package, then only send it
+        // to registered receivers.  We don't want to launch a swath of apps for every
+        // little component state change.
+        final int flags = !componentNames.contains(packageName)
+                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
+        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
                 new int[] {UserHandle.getUserId(packageUid)});
     }
 
@@ -15023,20 +14842,23 @@
     static class DumpState {
         public static final int DUMP_LIBS = 1 << 0;
         public static final int DUMP_FEATURES = 1 << 1;
-        public static final int DUMP_RESOLVERS = 1 << 2;
-        public static final int DUMP_PERMISSIONS = 1 << 3;
-        public static final int DUMP_PACKAGES = 1 << 4;
-        public static final int DUMP_SHARED_USERS = 1 << 5;
-        public static final int DUMP_MESSAGES = 1 << 6;
-        public static final int DUMP_PROVIDERS = 1 << 7;
-        public static final int DUMP_VERIFIERS = 1 << 8;
-        public static final int DUMP_PREFERRED = 1 << 9;
-        public static final int DUMP_PREFERRED_XML = 1 << 10;
-        public static final int DUMP_KEYSETS = 1 << 11;
-        public static final int DUMP_VERSION = 1 << 12;
-        public static final int DUMP_INSTALLS = 1 << 13;
-        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14;
-        public static final int DUMP_DOMAIN_PREFERRED = 1 << 15;
+        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
+        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
+        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
+        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
+        public static final int DUMP_PERMISSIONS = 1 << 6;
+        public static final int DUMP_PACKAGES = 1 << 7;
+        public static final int DUMP_SHARED_USERS = 1 << 8;
+        public static final int DUMP_MESSAGES = 1 << 9;
+        public static final int DUMP_PROVIDERS = 1 << 10;
+        public static final int DUMP_VERIFIERS = 1 << 11;
+        public static final int DUMP_PREFERRED = 1 << 12;
+        public static final int DUMP_PREFERRED_XML = 1 << 13;
+        public static final int DUMP_KEYSETS = 1 << 14;
+        public static final int DUMP_VERSION = 1 << 15;
+        public static final int DUMP_INSTALLS = 1 << 16;
+        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
+        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
 
         public static final int OPTION_SHOW_FILTERS = 1 << 0;
 
@@ -15135,9 +14957,9 @@
                 pw.println("    -h: print this help");
                 pw.println("  cmd may be one of:");
                 pw.println("    l[ibraries]: list known shared libraries");
-                pw.println("    f[ibraries]: list device features");
+                pw.println("    f[eatures]: list device features");
                 pw.println("    k[eysets]: print known keysets");
-                pw.println("    r[esolvers]: dump intent resolvers");
+                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
                 pw.println("    perm[issions]: dump permissions");
                 pw.println("    permission [name ...]: dump declaration and use of given permission");
                 pw.println("    pref[erred]: print preferred package settings");
@@ -15204,7 +15026,29 @@
             } else if ("f".equals(cmd) || "features".equals(cmd)) {
                 dumpState.setDump(DumpState.DUMP_FEATURES);
             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
-                dumpState.setDump(DumpState.DUMP_RESOLVERS);
+                if (opti >= args.length) {
+                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
+                            | DumpState.DUMP_SERVICE_RESOLVERS
+                            | DumpState.DUMP_RECEIVER_RESOLVERS
+                            | DumpState.DUMP_CONTENT_RESOLVERS);
+                } else {
+                    while (opti < args.length) {
+                        String name = args[opti];
+                        if ("a".equals(name) || "activity".equals(name)) {
+                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
+                        } else if ("s".equals(name) || "service".equals(name)) {
+                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
+                        } else if ("r".equals(name) || "receiver".equals(name)) {
+                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
+                        } else if ("c".equals(name) || "content".equals(name)) {
+                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
+                        } else {
+                            pw.println("Error: unknown resolver table type: " + name);
+                            return;
+                        }
+                        opti++;
+                    }
+                }
             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
             } else if ("permission".equals(cmd)) {
@@ -15371,22 +15215,28 @@
                 }
             }
 
-            if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
+            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
                         : "Activity Resolver Table:", "  ", packageName,
                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
                     dumpState.setTitlePrinted(true);
                 }
+            }
+            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
                         : "Receiver Resolver Table:", "  ", packageName,
                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
                     dumpState.setTitlePrinted(true);
                 }
+            }
+            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
                         : "Service Resolver Table:", "  ", packageName,
                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
                     dumpState.setTitlePrinted(true);
                 }
+            }
+            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
                         : "Provider Resolver Table:", "  ", packageName,
                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
@@ -15833,7 +15683,7 @@
             }
             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
-            sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
+            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
         }
     }
 
@@ -16150,13 +16000,14 @@
             }
         }
 
+        final StorageManager sm = mContext.getSystemService(StorageManager.class);
         final UserManager um = mContext.getSystemService(UserManager.class);
         for (UserInfo user : um.getUsers()) {
             final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id);
             if (userDir.exists()) continue;
 
             try {
-                UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id);
+                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber);
                 UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
             } catch (IOException e) {
                 Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
@@ -16234,13 +16085,18 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
 
         final int moveId = mNextMoveId.getAndIncrement();
-        try {
-            movePackageInternal(packageName, volumeUuid, moveId);
-        } catch (PackageManagerException e) {
-            Slog.w(TAG, "Failed to move " + packageName, e);
-            mMoveCallbacks.notifyStatusChanged(moveId,
-                    PackageManager.MOVE_FAILED_INTERNAL_ERROR);
-        }
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    movePackageInternal(packageName, volumeUuid, moveId);
+                } catch (PackageManagerException e) {
+                    Slog.w(TAG, "Failed to move " + packageName, e);
+                    mMoveCallbacks.notifyStatusChanged(moveId,
+                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
+                }
+            }
+        });
         return moveId;
     }
 
@@ -16532,23 +16388,26 @@
     }
 
     /** Called by UserManagerService */
-    void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
-        mDirtyUsers.remove(userHandle);
-        mSettings.removeUserLPw(userHandle);
-        mPendingBroadcasts.remove(userHandle);
-        if (mInstaller != null) {
-            // Technically, we shouldn't be doing this with the package lock
-            // held.  However, this is very rare, and there is already so much
-            // other disk I/O going on, that we'll let it slide for now.
-            final StorageManager storage = mContext.getSystemService(StorageManager.class);
-            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
-                final String volumeUuid = vol.getFsUuid();
-                if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
-                mInstaller.removeUserDataDirs(volumeUuid, userHandle);
+    void cleanUpUser(UserManagerService userManager, int userHandle) {
+        synchronized (mPackages) {
+            mDirtyUsers.remove(userHandle);
+            mUserNeedsBadging.delete(userHandle);
+            mSettings.removeUserLPw(userHandle);
+            mPendingBroadcasts.remove(userHandle);
+        }
+        synchronized (mInstallLock) {
+            if (mInstaller != null) {
+                final StorageManager storage = mContext.getSystemService(StorageManager.class);
+                for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+                    final String volumeUuid = vol.getFsUuid();
+                    if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
+                    mInstaller.removeUserDataDirs(volumeUuid, userHandle);
+                }
+            }
+            synchronized (mPackages) {
+                removeUnusedPackagesLILPw(userManager, userHandle);
             }
         }
-        mUserNeedsBadging.delete(userHandle);
-        removeUnusedPackagesLILPw(userManager, userHandle);
     }
 
     /**
@@ -16598,12 +16457,18 @@
     }
 
     /** Called by UserManagerService */
-    void createNewUserLILPw(int userHandle) {
+    void createNewUser(int userHandle) {
         if (mInstaller != null) {
-            mInstaller.createUserConfig(userHandle);
-            mSettings.createNewUserLILPw(this, mInstaller, userHandle);
-            applyFactoryDefaultBrowserLPw(userHandle);
-            primeDomainVerificationsLPw(userHandle);
+            synchronized (mInstallLock) {
+                synchronized (mPackages) {
+                    mInstaller.createUserConfig(userHandle);
+                    mSettings.createNewUserLILPw(this, mInstaller, userHandle);
+                }
+            }
+            synchronized (mPackages) {
+                applyFactoryDefaultBrowserLPw(userHandle);
+                primeDomainVerificationsLPw(userHandle);
+            }
         }
     }
 
@@ -16777,27 +16642,6 @@
         }
     }
 
-    public void getUsageStatsIfNoPackageUsageInfo() {
-        if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
-            UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
-            if (usm == null) {
-                throw new IllegalStateException("UsageStatsManager must be initialized");
-            }
-            long now = System.currentTimeMillis();
-            Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
-            for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
-                String packageName = entry.getKey();
-                PackageParser.Package pkg = mPackages.get(packageName);
-                if (pkg == null) {
-                    continue;
-                }
-                UsageStats usage = entry.getValue();
-                pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
-                mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
-            }
-        }
-    }
-
     /**
      * Check and throw if the given before/after packages would be considered a
      * downgrade.
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index c259ac2..2cedc9c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1,33 +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.server.pm;
 
+import android.app.ActivityManager;
 import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.InstrumentationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
+import android.content.pm.PackageInstaller.SessionInfo;
+import android.content.pm.PackageInstaller.SessionParams;
+import android.content.pm.ResolveInfo;
 import android.content.res.AssetManager;
 import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ShellCommand;
 import android.os.UserHandle;
+import android.text.TextUtils;
 
+import android.util.PrintWriterPrinter;
+import com.android.internal.util.SizedInputStream;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.WeakHashMap;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
 
 class PackageManagerShellCommand extends ShellCommand {
     final IPackageManager mInterface;
     final private WeakHashMap<String, Resources> mResourceCache =
             new WeakHashMap<String, Resources>();
+    int mTargetUser;
 
     PackageManagerShellCommand(PackageManagerService service) {
         mInterface = service;
@@ -42,8 +86,27 @@
         final PrintWriter pw = getOutPrintWriter();
         try {
             switch(cmd) {
+                case "install":
+                    return runInstall();
+                case "install-abandon":
+                case "install-destroy":
+                    return runInstallAbandon();
+                case "install-commit":
+                    return runInstallCommit();
+                case "install-create":
+                    return runInstallCreate();
+                case "install-write":
+                    return runInstallWrite();
                 case "list":
                     return runList();
+                case "uninstall":
+                    return runUninstall();
+                case "query-intent-activities":
+                    return runQueryIntentActivities();
+                case "query-intent-services":
+                    return runQueryIntentServices();
+                case "query-intent-receivers":
+                    return runQueryIntentReceivers();
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -53,6 +116,65 @@
         return -1;
     }
 
+    private int runInstall() throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+        final InstallParams params = makeInstallParams();
+        final int sessionId = doCreateSession(params.sessionParams,
+                params.installerPackageName, params.userId);
+
+        final String inPath = getNextArg();
+        if (inPath == null && params.sessionParams.sizeBytes == 0) {
+            pw.println("Error: must either specify a package size or an APK file");
+            return 1;
+        }
+        if (doWriteSession(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk") != 0) {
+            return 1;
+        }
+        if (doCommitSession(sessionId) != 0) {
+            return 1;
+        }
+        return 0;
+    }
+
+    private int runInstallAbandon() throws RemoteException {
+        final int sessionId = Integer.parseInt(getNextArg());
+        return doAbandonSession(sessionId);
+    }
+
+    private int runInstallCommit() throws RemoteException {
+        final int sessionId = Integer.parseInt(getNextArg());
+        return doCommitSession(sessionId);
+    }
+
+    private int runInstallCreate() throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+        final InstallParams installParams = makeInstallParams();
+        final int sessionId = doCreateSession(installParams.sessionParams,
+                installParams.installerPackageName, installParams.userId);
+
+        // NOTE: adb depends on parsing this string
+        pw.println("Success: created install session [" + sessionId + "]");
+        return 0;
+    }
+
+    private int runInstallWrite() throws RemoteException {
+        long sizeBytes = -1;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if (opt.equals("-S")) {
+                sizeBytes = Long.parseLong(getNextArg());
+            } else {
+                throw new IllegalArgumentException("Unknown option: " + opt);
+            }
+        }
+
+        final int sessionId = Integer.parseInt(getNextArg());
+        final String splitName = getNextArg();
+        final String path = getNextArg();
+        return doWriteSession(sessionId, path, sizeBytes, splitName);
+    }
+
     private int runList() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final String type = getNextArg();
@@ -228,7 +350,7 @@
                         listThirdParty = true;
                         break;
                     case "--user":
-                        userId = Integer.parseInt(getNextArg());
+                        userId = UserHandle.parseUserArg(getNextArgRequired());
                         break;
                     default:
                         pw.println("Error: Unknown option: " + opt);
@@ -363,6 +485,377 @@
         return 0;
     }
 
+    private int runUninstall() throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+        int flags = 0;
+        int userId = UserHandle.USER_ALL;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-k":
+                    flags |= PackageManager.DELETE_KEEP_DATA;
+                    break;
+                case "--user":
+                    userId = UserHandle.parseUserArg(getNextArgRequired());
+                    break;
+                default:
+                    pw.println("Error: Unknown option: " + opt);
+                    return 1;
+            }
+        }
+
+        String packageName = getNextArg();
+        if (packageName == null) {
+            pw.println("Error: package name not specified");
+            return 1;
+        }
+
+        userId = translateUserId(userId, "runUninstall");
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_SYSTEM;
+            flags |= PackageManager.DELETE_ALL_USERS;
+        } else {
+            final PackageInfo info = mInterface.getPackageInfo(packageName, 0, userId);
+            if (info == null) {
+                pw.println("Failure - not installed for " + userId);
+                return 1;
+            }
+            final boolean isSystem =
+                    (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+            // If we are being asked to delete a system app for just one
+            // user set flag so it disables rather than reverting to system
+            // version of the app.
+            if (isSystem) {
+                flags |= PackageManager.DELETE_SYSTEM_APP;
+            }
+        }
+
+        final LocalIntentReceiver receiver = new LocalIntentReceiver();
+        mInterface.getPackageInstaller().uninstall(packageName, null /*callerPackageName*/, flags,
+                receiver.getIntentSender(), userId);
+
+        final Intent result = receiver.getResult();
+        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                PackageInstaller.STATUS_FAILURE);
+        if (status == PackageInstaller.STATUS_SUCCESS) {
+            pw.println("Success");
+            return 0;
+        } else {
+            pw.println("Failure ["
+                    + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+            return 1;
+        }
+    }
+
+    private Intent parseIntentAndUser() throws URISyntaxException {
+        mTargetUser = UserHandle.USER_CURRENT;
+        Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
+            @Override
+            public boolean handleOption(String opt, ShellCommand cmd) {
+                if ("--user".equals(opt)) {
+                    mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
+                    return true;
+                }
+                return false;
+            }
+        });
+        mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                Binder.getCallingUid(), mTargetUser, false, false, null, null);
+        return intent;
+    }
+
+    private int runQueryIntentActivities() {
+        Intent intent;
+        try {
+            intent = parseIntentAndUser();
+        } catch (URISyntaxException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+        try {
+            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0,
+                    mTargetUser);
+            PrintWriter pw = getOutPrintWriter();
+            if (result == null || result.size() <= 0) {
+                pw.println("No activities found");
+            } else {
+                pw.print(result.size()); pw.println(" activities found:");
+                PrintWriterPrinter pr = new PrintWriterPrinter(pw);
+                for (int i=0; i<result.size(); i++) {
+                    pw.print("  Activity #"); pw.print(i); pw.println(":");
+                    result.get(i).dump(pr, "    ");
+                }
+            }
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed calling service", e);
+        }
+        return 0;
+    }
+
+    private int runQueryIntentServices() {
+        Intent intent;
+        try {
+            intent = parseIntentAndUser();
+        } catch (URISyntaxException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+        try {
+            List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0,
+                    mTargetUser);
+            PrintWriter pw = getOutPrintWriter();
+            if (result == null || result.size() <= 0) {
+                pw.println("No services found");
+            } else {
+                pw.print(result.size()); pw.println(" services found:");
+                PrintWriterPrinter pr = new PrintWriterPrinter(pw);
+                for (int i=0; i<result.size(); i++) {
+                    pw.print("  Service #"); pw.print(i); pw.println(":");
+                    result.get(i).dump(pr, "    ");
+                }
+            }
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed calling service", e);
+        }
+        return 0;
+    }
+
+    private int runQueryIntentReceivers() {
+        Intent intent;
+        try {
+            intent = parseIntentAndUser();
+        } catch (URISyntaxException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+        try {
+            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0,
+                    mTargetUser);
+            PrintWriter pw = getOutPrintWriter();
+            if (result == null || result.size() <= 0) {
+                pw.println("No receivers found");
+            } else {
+                pw.print(result.size()); pw.println(" receivers found:");
+                PrintWriterPrinter pr = new PrintWriterPrinter(pw);
+                for (int i=0; i<result.size(); i++) {
+                    pw.print("  Receiver #"); pw.print(i); pw.println(":");
+                    result.get(i).dump(pr, "    ");
+                }
+            }
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed calling service", e);
+        }
+        return 0;
+    }
+
+    private static class InstallParams {
+        SessionParams sessionParams;
+        String installerPackageName;
+        int userId = UserHandle.USER_ALL;
+    }
+
+    private InstallParams makeInstallParams() {
+        final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
+        final InstallParams params = new InstallParams();
+        params.sessionParams = sessionParams;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-l":
+                    sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+                    break;
+                case "-r":
+                    sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
+                    break;
+                case "-i":
+                    params.installerPackageName = getNextArg();
+                    if (params.installerPackageName == null) {
+                        throw new IllegalArgumentException("Missing installer package");
+                    }
+                    break;
+                case "-t":
+                    sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
+                    break;
+                case "-s":
+                    sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
+                    break;
+                case "-f":
+                    sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
+                    break;
+                case "-d":
+                    sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+                    break;
+                case "-g":
+                    sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
+                    break;
+                case "--originating-uri":
+                    sessionParams.originatingUri = Uri.parse(getNextArg());
+                    break;
+                case "--referrer":
+                    sessionParams.referrerUri = Uri.parse(getNextArg());
+                    break;
+                case "-p":
+                    sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
+                    sessionParams.appPackageName = getNextArg();
+                    if (sessionParams.appPackageName == null) {
+                        throw new IllegalArgumentException("Missing inherit package name");
+                    }
+                    break;
+                case "-S":
+                    sessionParams.setSize(Long.parseLong(getNextArg()));
+                    break;
+                case "--abi":
+                    sessionParams.abiOverride = checkAbiArgument(getNextArg());
+                    break;
+                case "--user":
+                    params.userId = UserHandle.parseUserArg(getNextArgRequired());
+                    break;
+                case "--install-location":
+                    sessionParams.installLocation = Integer.parseInt(getNextArg());
+                    break;
+                case "--force-uuid":
+                    sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
+                    sessionParams.volumeUuid = getNextArg();
+                    if ("internal".equals(sessionParams.volumeUuid)) {
+                        sessionParams.volumeUuid = null;
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown option " + opt);
+            }
+        }
+        return params;
+    }
+
+    private static String checkAbiArgument(String abi) {
+        if (TextUtils.isEmpty(abi)) {
+            throw new IllegalArgumentException("Missing ABI argument");
+        }
+
+        if ("-".equals(abi)) {
+            return abi;
+        }
+
+        final String[] supportedAbis = Build.SUPPORTED_ABIS;
+        for (String supportedAbi : supportedAbis) {
+            if (supportedAbi.equals(abi)) {
+                return abi;
+            }
+        }
+
+        throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
+    }
+
+    private int translateUserId(int userId, String logContext) {
+        return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+                userId, true, true, logContext, "pm command");
+    }
+
+    private int doCreateSession(SessionParams params, String installerPackageName, int userId)
+            throws RemoteException {
+        userId = translateUserId(userId, "runInstallCreate");
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_SYSTEM;
+            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
+        }
+
+        final int sessionId = mInterface.getPackageInstaller()
+                .createSession(params, installerPackageName, userId);
+        return sessionId;
+    }
+
+    private int doWriteSession(int sessionId, String inPath, long sizeBytes, String splitName)
+            throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+        if ("-".equals(inPath)) {
+            inPath = null;
+        } else if (inPath != null) {
+            final File file = new File(inPath);
+            if (file.isFile()) {
+                sizeBytes = file.length();
+            }
+        }
+
+        final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId);
+
+        PackageInstaller.Session session = null;
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            session = new PackageInstaller.Session(
+                    mInterface.getPackageInstaller().openSession(sessionId));
+
+            if (inPath != null) {
+                in = new FileInputStream(inPath);
+            } else {
+                in = new SizedInputStream(getInputStream(), sizeBytes);
+            }
+            out = session.openWrite(splitName, 0, sizeBytes);
+
+            int total = 0;
+            byte[] buffer = new byte[65536];
+            int c;
+            while ((c = in.read(buffer)) != -1) {
+                total += c;
+                out.write(buffer, 0, c);
+
+                if (info.sizeBytes > 0) {
+                    final float fraction = ((float) c / (float) info.sizeBytes);
+                    session.addProgress(fraction);
+                }
+            }
+            session.fsync(out);
+
+            pw.println("Success: streamed " + total + " bytes");
+            return 0;
+        } catch (IOException e) {
+            pw.println("Error: failed to write; " + e.getMessage());
+            return 1;
+        } finally {
+            IoUtils.closeQuietly(out);
+            IoUtils.closeQuietly(in);
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    private int doCommitSession(int sessionId) throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+        PackageInstaller.Session session = null;
+        try {
+            session = new PackageInstaller.Session(
+                    mInterface.getPackageInstaller().openSession(sessionId));
+
+            final LocalIntentReceiver receiver = new LocalIntentReceiver();
+            session.commit(receiver.getIntentSender());
+
+            final Intent result = receiver.getResult();
+            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                    PackageInstaller.STATUS_FAILURE);
+            if (status == PackageInstaller.STATUS_SUCCESS) {
+                pw.println("Success");
+            } else {
+                pw.println("Failure ["
+                        + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+                pw.println("Failure details: " + result.getExtras());
+            }
+            return status;
+        } finally {
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    private int doAbandonSession(int sessionId) throws RemoteException {
+        final PrintWriter pw = getOutPrintWriter();
+        PackageInstaller.Session session = null;
+        try {
+            session = new PackageInstaller.Session(
+                    mInterface.getPackageInstaller().openSession(sessionId));
+            session.abandon();
+            pw.println("Success");
+            return 0;
+        } finally {
+            IoUtils.closeQuietly(session);
+        }
+    }
+
     private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
             boolean summary, int startProtectionLevel, int endProtectionLevel)
                     throws RemoteException {
@@ -523,7 +1016,43 @@
         pw.println("      -s: short summary");
         pw.println("      -d: only list dangerous permissions");
         pw.println("      -u: list only the permissions users will see");
-        pw.println("");
+        pw.println("  query-intent-activities [--user USER_ID] INTENT");
+        pw.println("    Prints all activities that can handle the given Intent.");
+        pw.println("  query-intent-services [--user USER_ID] INTENT");
+        pw.println("    Prints all services that can handle the given Intent.");
+        pw.println("  query-intent-receivers [--user USER_ID] INTENT");
+        pw.println("    Prints all broadcast receivers that can handle the given Intent.");
+        pw.println();
+        Intent.printIntentArgsHelp(pw , "");
+    }
+
+    private static class LocalIntentReceiver {
+        private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
+
+        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
+            @Override
+            public int send(int code, Intent intent, String resolvedType,
+                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
+                try {
+                    mResult.offer(intent, 5, TimeUnit.SECONDS);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+                return 0;
+            }
+        };
+
+        public IntentSender getIntentSender() {
+            return new IntentSender((IIntentSender) mLocalSender);
+        }
+
+        public Intent getResult() {
+            try {
+                return mResult.take();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
     }
 }
 
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 5d8b1d2..903d12b 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -103,6 +103,9 @@
     // Append privapp to existing seinfo label
     private static final String PRIVILEGED_APP_STR = ":privapp";
 
+    // Append autoplay to existing seinfo label
+    private static final String AUTOPLAY_APP_STR = ":autoplayapp";
+
     /**
      * Load the mac_permissions.xml file containing all seinfo assignments used to
      * label apps. The loaded mac_permissions.xml file is determined by the
@@ -316,6 +319,9 @@
             }
         }
 
+        if (pkg.applicationInfo.isAutoPlayApp())
+            pkg.applicationInfo.seinfo += AUTOPLAY_APP_STR;
+
         if (pkg.applicationInfo.isPrivilegedApp())
             pkg.applicationInfo.seinfo += PRIVILEGED_APP_STR;
 
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8b99305..1d299d7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2248,7 +2248,8 @@
 
             StringBuilder sb = new StringBuilder();
             for (final PackageSetting pkg : mPackages.values()) {
-                if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
+                if (pkg.pkg == null || pkg.pkg.applicationInfo == null
+                        || pkg.pkg.applicationInfo.dataDir == null) {
                     Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
                     continue;
                 }
@@ -3750,8 +3751,13 @@
     private String compToString(ArraySet<String> cmp) {
         return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
     }
- 
-    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
+
+    boolean isEnabledAndVisibleLPr(ComponentInfo componentInfo, int flags, int userId) {
+        return isEnabledLPr(componentInfo, flags, userId)
+                && isVisibleLPr(componentInfo, flags);
+    }
+
+    private boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
         if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
             return true;
         }
@@ -3792,6 +3798,17 @@
         return componentInfo.enabled;
     }
 
+    private boolean isVisibleLPr(ComponentInfo componentInfo, int flags) {
+        if ((flags & PackageManager.GET_ENCRYPTION_UNAWARE_COMPONENTS) != 0) {
+            return true;
+        }
+        if ((flags & PackageManager.FLAG_USER_RUNNING_WITH_AMNESIA) != 0) {
+            // When running with amnesia, we can only run encryption-aware apps
+            return componentInfo.encryptionAware;
+        }
+        return true;
+    }
+
     String getInstallerPackageNameLPr(String packageName) {
         final PackageSetting pkg = mPackages.get(packageName);
         if (pkg == null) {
@@ -3844,7 +3861,7 @@
             if (pkgSetting.getNotLaunched(userId)) {
                 if (pkgSetting.installerPackageName != null) {
                     yucky.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
-                            pkgSetting.name, null,
+                            pkgSetting.name, null, 0,
                             pkgSetting.installerPackageName, null, new int[] {userId});
                 }
                 pkgSetting.setNotLaunched(false, userId);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 621ae2d..ab0b182 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -52,6 +52,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
+import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.system.ErrnoException;
@@ -96,8 +97,7 @@
  *
  * Method naming convention:
  * <ul>
- * <li> Methods suffixed with "LILP" should be called within {@link #mInstallLock} and
- * {@link #mPackagesLock} locks obtained in the respective order.
+ * <li> Methods suffixed with "LP" should be called within the {@link #mPackagesLock} lock.
  * <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock.
  * <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock.
  * </ul>
@@ -163,7 +163,6 @@
 
     private final Context mContext;
     private final PackageManagerService mPm;
-    private final Object mInstallLock;
     private final Object mPackagesLock;
     // Short-term lock for internal state, when interaction/sync with PM is not required
     private final Object mUsersLock = new Object();
@@ -214,6 +213,7 @@
     @GuardedBy("mRestrictionsLock")
     private final SparseArray<Bundle> mAppliedUserRestrictions = new SparseArray<>();
 
+    @GuardedBy("mGuestRestrictions")
     private final Bundle mGuestRestrictions = new Bundle();
 
     /**
@@ -225,6 +225,7 @@
 
     @GuardedBy("mUsersLock")
     private int[] mUserIds;
+    @GuardedBy("mPackagesLock")
     private int mNextSerialNumber;
     private int mUserVersion = 0;
 
@@ -232,6 +233,10 @@
 
     private final LocalService mLocalService;
 
+    @GuardedBy("mUserRestrictionsListeners")
+    private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
+            new ArrayList<>();
+
     private static UserManagerService sInstance;
 
     public static UserManagerService getInstance() {
@@ -240,11 +245,9 @@
         }
     }
 
-    /**
-     * Available for testing purposes.
-     */
-    UserManagerService(File dataDir, File baseUserPath) {
-        this(null, null, new Object(), new Object(), dataDir, baseUserPath);
+    @VisibleForTesting
+    UserManagerService(File dataDir) {
+        this(null, null, new Object(), dataDir);
     }
 
     /**
@@ -252,68 +255,53 @@
      * associated with the package manager, and the given lock is the
      * package manager's own lock.
      */
-    UserManagerService(Context context, PackageManagerService pm,
-            Object installLock, Object packagesLock) {
-        this(context, pm, installLock, packagesLock,
-                Environment.getDataDirectory(),
-                new File(Environment.getDataDirectory(), "user"));
+    UserManagerService(Context context, PackageManagerService pm, Object packagesLock) {
+        this(context, pm, packagesLock, Environment.getDataDirectory());
     }
 
-    /**
-     * Available for testing purposes.
-     */
     private UserManagerService(Context context, PackageManagerService pm,
-            Object installLock, Object packagesLock,
-            File dataDir, File baseUserPath) {
+            Object packagesLock, File dataDir) {
         mContext = context;
         mPm = pm;
-        mInstallLock = installLock;
         mPackagesLock = packagesLock;
         mHandler = new MainHandler();
-        synchronized (mInstallLock) {
-            synchronized (mPackagesLock) {
-                mUsersDir = new File(dataDir, USER_INFO_DIR);
-                mUsersDir.mkdirs();
-                // Make zeroth user directory, for services to migrate their files to that location
-                File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
-                userZeroDir.mkdirs();
-                FileUtils.setPermissions(mUsersDir.toString(),
-                        FileUtils.S_IRWXU|FileUtils.S_IRWXG
-                        |FileUtils.S_IROTH|FileUtils.S_IXOTH,
-                        -1, -1);
-                mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
-                initDefaultGuestRestrictions();
-                readUserListLILP();
-                sInstance = this;
-            }
+        synchronized (mPackagesLock) {
+            mUsersDir = new File(dataDir, USER_INFO_DIR);
+            mUsersDir.mkdirs();
+            // Make zeroth user directory, for services to migrate their files to that location
+            File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
+            userZeroDir.mkdirs();
+            FileUtils.setPermissions(mUsersDir.toString(),
+                    FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
+                    -1, -1);
+            mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
+            initDefaultGuestRestrictions();
+            readUserListLP();
+            sInstance = this;
         }
         mLocalService = new LocalService();
         LocalServices.addService(UserManagerInternal.class, mLocalService);
     }
 
     void systemReady() {
-        synchronized (mInstallLock) {
-            synchronized (mPackagesLock) {
-                synchronized (mUsersLock) {
-                    // Prune out any partially created/partially removed users.
-                    ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
-                    final int userSize = mUsers.size();
-                    for (int i = 0; i < userSize; i++) {
-                        UserInfo ui = mUsers.valueAt(i);
-                        if ((ui.partial || ui.guestToRemove) && i != 0) {
-                            partials.add(ui);
-                        }
-                    }
-                    final int partialsSize = partials.size();
-                    for (int i = 0; i < partialsSize; i++) {
-                        UserInfo ui = partials.get(i);
-                        Slog.w(LOG_TAG, "Removing partially created user " + ui.id
-                                + " (name=" + ui.name + ")");
-                        removeUserStateLILP(ui.id);
-                    }
+        // Prune out any partially created/partially removed users.
+        ArrayList<UserInfo> partials = new ArrayList<>();
+        synchronized (mUsersLock) {
+            final int userSize = mUsers.size();
+            for (int i = 0; i < userSize; i++) {
+                UserInfo ui = mUsers.valueAt(i);
+                if ((ui.partial || ui.guestToRemove) && i != 0) {
+                    partials.add(ui);
                 }
             }
         }
+        final int partialsSize = partials.size();
+        for (int i = 0; i < partialsSize; i++) {
+            UserInfo ui = partials.get(i);
+            Slog.w(LOG_TAG, "Removing partially created user " + ui.id
+                    + " (name=" + ui.name + ")");
+            removeUserState(ui.id);
+        }
         onUserForeground(UserHandle.USER_SYSTEM);
         mAppOpsService = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
@@ -622,17 +610,22 @@
 
     public void makeInitialized(int userId) {
         checkManageUsersPermission("makeInitialized");
-        synchronized (mPackagesLock) {
-            UserInfo info = getUserInfoNoChecks(userId);
+        boolean scheduleWriteUser = false;
+        UserInfo info;
+        synchronized (mUsersLock) {
+            info = mUsers.get(userId);
             if (info == null || info.partial) {
                 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId);
-                // TODO Check if we should return here instead of a null check below
+                return;
             }
-            if (info != null && (info.flags&UserInfo.FLAG_INITIALIZED) == 0) {
+            if ((info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
                 info.flags |= UserInfo.FLAG_INITIALIZED;
-                scheduleWriteUserLP(info);
+                scheduleWriteUser = true;
             }
         }
+        if (scheduleWriteUser) {
+            scheduleWriteUser(info);
+        }
     }
 
     /**
@@ -640,17 +633,18 @@
      * restrictions.
      */
     private void initDefaultGuestRestrictions() {
-        if (mGuestRestrictions.isEmpty()) {
-            mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);
-            mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
+        synchronized (mGuestRestrictions) {
+            if (mGuestRestrictions.isEmpty()) {
+                mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);
+                mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
+            }
         }
     }
 
     @Override
     public Bundle getDefaultGuestRestrictions() {
         checkManageUsersPermission("getDefaultGuestRestrictions");
-        // TODO Switch to mGuestRestrictions for locking
-        synchronized (mPackagesLock) {
+        synchronized (mGuestRestrictions) {
             return new Bundle(mGuestRestrictions);
         }
     }
@@ -658,12 +652,12 @@
     @Override
     public void setDefaultGuestRestrictions(Bundle restrictions) {
         checkManageUsersPermission("setDefaultGuestRestrictions");
-        synchronized (mInstallLock) {
-            synchronized (mPackagesLock) {
-                mGuestRestrictions.clear();
-                mGuestRestrictions.putAll(restrictions);
-                writeUserListLILP();
-            }
+        synchronized (mGuestRestrictions) {
+            mGuestRestrictions.clear();
+            mGuestRestrictions.putAll(restrictions);
+        }
+        synchronized (mPackagesLock) {
+            writeUserListLP();
         }
     }
 
@@ -770,6 +764,7 @@
             Preconditions.checkState(mCachedEffectiveUserRestrictions.get(userId)
                     != newRestrictions);
             mBaseUserRestrictions.put(userId, newRestrictions);
+            scheduleWriteUser(getUserInfoNoChecks(userId));
         }
 
         final Bundle effective = computeEffectiveUserRestrictionsLR(userId);
@@ -781,7 +776,14 @@
 
     @GuardedBy("mRestrictionsLock")
     private void applyUserRestrictionsLR(int userId, Bundle newRestrictions) {
-        final Bundle prevRestrictions = mAppliedUserRestrictions.get(userId);
+        if (newRestrictions == null) {
+            newRestrictions = Bundle.EMPTY;
+        }
+
+        Bundle prevRestrictions = mAppliedUserRestrictions.get(userId);
+        if (prevRestrictions == null) {
+            prevRestrictions = Bundle.EMPTY;
+        }
 
         if (DBG) {
             Log.d(LOG_TAG, "applyUserRestrictionsRL userId=" + userId
@@ -797,12 +799,36 @@
             Binder.restoreCallingIdentity(token);
         }
 
-        UserRestrictionsUtils.applyUserRestrictions(
+        UserRestrictionsUtils.applyUserRestrictionsLR(
                 mContext, userId, newRestrictions, prevRestrictions);
 
+        notifyUserRestrictionsListeners(userId, newRestrictions, prevRestrictions);
+
         mAppliedUserRestrictions.put(userId, new Bundle(newRestrictions));
     }
 
+    private void notifyUserRestrictionsListeners(final int userId,
+            Bundle newRestrictions, Bundle prevRestrictions) {
+
+        final Bundle newRestrictionsFinal = new Bundle(newRestrictions);
+        final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions);
+
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                final UserRestrictionsListener[] listeners;
+                synchronized (mUserRestrictionsListeners) {
+                    listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()];
+                    mUserRestrictionsListeners.toArray(listeners);
+                }
+                for (int i = 0; i < listeners.length; i++) {
+                    listeners[i].onUserRestrictionsChanged(userId,
+                            newRestrictionsFinal, prevRestrictionsFinal);
+                }
+            }
+        });
+    }
+
     @GuardedBy("mRestrictionsLock")
     private void updateEffectiveUserRestrictionsLR(int userId) {
         updateUserRestrictionsInternalLR(null, userId);
@@ -853,7 +879,7 @@
     }
 
     @Override
-    public boolean canAddMoreManagedProfiles(int userId) {
+    public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) {
         checkManageUsersPermission("check if more managed profiles can be added.");
         if (ActivityManager.isLowRamDeviceStatic()) {
             return false;
@@ -863,8 +889,9 @@
             return false;
         }
         // Limit number of managed profiles that can be created
-        int managedProfilesCount = getProfiles(userId, true).size() - 1;
-        if (managedProfilesCount >= MAX_MANAGED_PROFILES) {
+        final int managedProfilesCount = getProfiles(userId, true).size() - 1;
+        final int profilesRemovedCount = managedProfilesCount > 0 && allowedToRemoveOne ? 1 : 0;
+        if (managedProfilesCount - profilesRemovedCount >= MAX_MANAGED_PROFILES) {
             return false;
         }
         synchronized(mUsersLock) {
@@ -872,9 +899,11 @@
             if (!userInfo.canHaveProfile()) {
                 return false;
             }
-            int usersCount = getAliveUsersExcludingGuestsCountLU();
+            int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU()
+                    - profilesRemovedCount;
             // We allow creating a managed profile in the special case where there is only one user.
-            return usersCount == 1 || usersCount < UserManager.getMaxSupportedUsers();
+            return usersCountAfterRemoving  == 1
+                    || usersCountAfterRemoving < UserManager.getMaxSupportedUsers();
         }
     }
 
@@ -956,9 +985,9 @@
         }
     }
 
-    private void readUserListLILP() {
+    private void readUserListLP() {
         if (!mUserListFile.exists()) {
-            fallbackToSingleUserLILP();
+            fallbackToSingleUserLP();
             return;
         }
         FileInputStream fis = null;
@@ -975,7 +1004,7 @@
 
             if (type != XmlPullParser.START_TAG) {
                 Slog.e(LOG_TAG, "Unable to read user list");
-                fallbackToSingleUserLILP();
+                fallbackToSingleUserLP();
                 return;
             }
 
@@ -996,7 +1025,7 @@
                     final String name = parser.getName();
                     if (name.equals(TAG_USER)) {
                         String id = parser.getAttributeValue(null, ATTR_ID);
-                        UserInfo user = readUserLILP(Integer.parseInt(id));
+                        UserInfo user = readUserLP(Integer.parseInt(id));
 
                         if (user != null) {
                             synchronized (mUsersLock) {
@@ -1011,8 +1040,10 @@
                                 && type != XmlPullParser.END_TAG) {
                             if (type == XmlPullParser.START_TAG) {
                                 if (parser.getName().equals(TAG_RESTRICTIONS)) {
-                                    UserRestrictionsUtils
-                                            .readRestrictions(parser, mGuestRestrictions);
+                                    synchronized (mGuestRestrictions) {
+                                        UserRestrictionsUtils
+                                                .readRestrictions(parser, mGuestRestrictions);
+                                    }
                                 }
                                 break;
                             }
@@ -1021,32 +1052,25 @@
                 }
             }
             updateUserIds();
-            upgradeIfNecessaryLILP();
-        } catch (IOException ioe) {
-            fallbackToSingleUserLILP();
-        } catch (XmlPullParserException pe) {
-            fallbackToSingleUserLILP();
+            upgradeIfNecessaryLP();
+        } catch (IOException | XmlPullParserException e) {
+            fallbackToSingleUserLP();
         } finally {
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                }
-            }
+            IoUtils.closeQuietly(fis);
         }
     }
 
     /**
      * Upgrade steps between versions, either for fixing bugs or changing the data format.
      */
-    private void upgradeIfNecessaryLILP() {
+    private void upgradeIfNecessaryLP() {
         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);
-                scheduleWriteUserLP(user);
+                scheduleWriteUser(user);
             }
             userVersion = 1;
         }
@@ -1056,7 +1080,7 @@
             UserInfo user = getUserInfoNoChecks(UserHandle.USER_SYSTEM);
             if ((user.flags & UserInfo.FLAG_INITIALIZED) == 0) {
                 user.flags |= UserInfo.FLAG_INITIALIZED;
-                scheduleWriteUserLP(user);
+                scheduleWriteUser(user);
             }
             userVersion = 2;
         }
@@ -1080,7 +1104,7 @@
                     if (!splitSystemUser && user.isRestricted()
                             && (user.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID)) {
                         user.restrictedProfileParentId = UserHandle.USER_SYSTEM;
-                        scheduleWriteUserLP(user);
+                        scheduleWriteUser(user);
                     }
                 }
             }
@@ -1092,11 +1116,11 @@
                     + USER_VERSION);
         } else {
             mUserVersion = userVersion;
-            writeUserListLILP();
+            writeUserListLP();
         }
     }
 
-    private void fallbackToSingleUserLILP() {
+    private void fallbackToSingleUserLP() {
         int flags = UserInfo.FLAG_INITIALIZED;
         // In split system user mode, the admin and primary flags are assigned to the first human
         // user.
@@ -1121,11 +1145,13 @@
         updateUserIds();
         initDefaultGuestRestrictions();
 
-        writeUserListLILP();
+        writeUserListLP();
         writeUserLP(system);
     }
 
-    private void scheduleWriteUserLP(UserInfo userInfo) {
+    private void scheduleWriteUser(UserInfo userInfo) {
+        // 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);
             mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY);
@@ -1205,8 +1231,7 @@
      *   <user id="2"></user>
      * </users>
      */
-    private void writeUserListLILP() {
-        // TODO Investigate removing a dependency on mInstallLock
+    private void writeUserListLP() {
         FileOutputStream fos = null;
         AtomicFile userListFile = new AtomicFile(mUserListFile);
         try {
@@ -1224,8 +1249,10 @@
             serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion));
 
             serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
-            UserRestrictionsUtils
-                    .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
+            synchronized (mGuestRestrictions) {
+                UserRestrictionsUtils
+                        .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
+            }
             serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
             int[] userIdsToWrite;
             synchronized (mUsersLock) {
@@ -1251,7 +1278,7 @@
         }
     }
 
-    private UserInfo readUserLILP(int id) {
+    private UserInfo readUserLP(int id) {
         int flags = 0;
         int serialNumber = id;
         String name = null;
@@ -1426,8 +1453,7 @@
     }
 
     private UserInfo createUserInternal(String name, int flags, int parentId) {
-        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
-                UserManager.DISALLOW_ADD_USER, false)) {
+        if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) {
             Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
             return null;
         }
@@ -1438,118 +1464,114 @@
         final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
         final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
         final long ident = Binder.clearCallingIdentity();
-        UserInfo userInfo = null;
+        UserInfo userInfo;
         final int userId;
         try {
-            synchronized (mInstallLock) {
-                synchronized (mPackagesLock) {
-                    UserInfo parent = null;
-                    if (parentId != UserHandle.USER_NULL) {
-                        synchronized (mUsersLock) {
-                            parent = getUserInfoLU(parentId);
-                        }
-                        if (parent == null) return null;
+            synchronized (mPackagesLock) {
+                UserInfo parent = null;
+                if (parentId != UserHandle.USER_NULL) {
+                    synchronized (mUsersLock) {
+                        parent = getUserInfoLU(parentId);
                     }
-                    if (isManagedProfile && !canAddMoreManagedProfiles(parentId)) {
-                        Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
+                    if (parent == null) return null;
+                }
+                if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) {
+                    Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
+                    return null;
+                }
+                if (!isGuest && !isManagedProfile && isUserLimitReached()) {
+                    // If we're not adding a guest user or a managed profile and the limit has
+                    // been reached, cannot add a user.
+                    return null;
+                }
+                // If we're adding a guest and there already exists one, bail.
+                if (isGuest && findCurrentGuestUser() != null) {
+                    return null;
+                }
+                // In legacy mode, restricted profile's parent can only be the owner user
+                if (isRestricted && !UserManager.isSplitSystemUser()
+                        && (parentId != UserHandle.USER_SYSTEM)) {
+                    Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
+                    return null;
+                }
+                if (isRestricted && UserManager.isSplitSystemUser()) {
+                    if (parent == null) {
+                        Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be "
+                                + "specified");
                         return null;
                     }
-                    if (!isGuest && !isManagedProfile && isUserLimitReached()) {
-                        // If we're not adding a guest user or a managed profile and the limit has
-                        // been reached, cannot add a user.
+                    if (!parent.canHaveProfile()) {
+                        Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
+                                + "created for the specified parent user id " + parentId);
                         return null;
                     }
-                    // If we're adding a guest and there already exists one, bail.
-                    if (isGuest && findCurrentGuestUser() != null) {
-                        return null;
+                }
+                // In split system user mode, we assign the first human user the primary flag.
+                // And if there is no device owner, we also assign the admin flag to primary user.
+                if (UserManager.isSplitSystemUser()
+                        && !isGuest && !isManagedProfile && getPrimaryUser() == null) {
+                    flags |= UserInfo.FLAG_PRIMARY;
+                    DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
+                            mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+                    if (devicePolicyManager == null
+                            || devicePolicyManager.getDeviceOwner() == null) {
+                        flags |= UserInfo.FLAG_ADMIN;
                     }
-                    // In legacy mode, restricted profile's parent can only be the owner user
-                    if (isRestricted && !UserManager.isSplitSystemUser()
-                            && (parentId != UserHandle.USER_SYSTEM)) {
-                        Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
-                        return null;
-                    }
-                    if (isRestricted && UserManager.isSplitSystemUser()) {
-                        if (parent == null) {
-                            Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be "
-                                    + "specified");
-                            return null;
-                        }
-                        if (!parent.canHaveProfile()) {
-                            Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
-                                    + "created for the specified parent user id " + parentId);
-                            return null;
-                        }
-                    }
-                    // In split system user mode, we assign the first human user the primary flag.
-                    // And if there is no device owner, we also assign the admin flag to primary
-                    // user.
-                    if (UserManager.isSplitSystemUser()
-                            && !isGuest && !isManagedProfile && getPrimaryUser() == null) {
-                        flags |= UserInfo.FLAG_PRIMARY;
-                        DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
-                                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-                        if (devicePolicyManager == null
-                                || devicePolicyManager.getDeviceOwner() == null) {
-                            flags |= UserInfo.FLAG_ADMIN;
-                        }
-                    }
-                    userId = getNextAvailableId();
-                    userInfo = new UserInfo(userId, name, null, flags);
-                    userInfo.serialNumber = mNextSerialNumber++;
-                    long now = System.currentTimeMillis();
-                    userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
-                    userInfo.partial = true;
-                    Environment.getUserSystemDirectory(userInfo.id).mkdirs();
+                }
+                userId = getNextAvailableId();
+                userInfo = new UserInfo(userId, name, null, flags);
+                userInfo.serialNumber = mNextSerialNumber++;
+                long now = System.currentTimeMillis();
+                userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
+                userInfo.partial = true;
+                Environment.getUserSystemDirectory(userInfo.id).mkdirs();
+                synchronized (mUsersLock) {
                     mUsers.put(userId, userInfo);
-                    writeUserListLILP();
-                    if (parent != null) {
-                        if (isManagedProfile) {
-                            if (parent.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
-                                parent.profileGroupId = parent.id;
-                                scheduleWriteUserLP(parent);
-                            }
-                            userInfo.profileGroupId = parent.profileGroupId;
-                        } else if (isRestricted) {
-                            if (!parent.canHaveProfile()) {
-                                Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
-                            }
-                            if (parent.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
-                                parent.restrictedProfileParentId = parent.id;
-                                scheduleWriteUserLP(parent);
-                            }
-                            userInfo.restrictedProfileParentId = parent.restrictedProfileParentId;
+                }
+                writeUserListLP();
+                if (parent != null) {
+                    if (isManagedProfile) {
+                        if (parent.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
+                            parent.profileGroupId = parent.id;
+                            writeUserLP(parent);
                         }
-                    }
-                    final StorageManager storage = mContext.getSystemService(StorageManager.class);
-                    for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
-                        final String volumeUuid = vol.getFsUuid();
-                        try {
-                            final File userDir = Environment.getDataUserDirectory(volumeUuid,
-                                    userId);
-                            prepareUserDirectory(mContext, volumeUuid, userId);
-                            enforceSerialNumber(userDir, userInfo.serialNumber);
-                        } catch (IOException e) {
-                            Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e);
+                        userInfo.profileGroupId = parent.profileGroupId;
+                    } else if (isRestricted) {
+                        if (parent.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
+                            parent.restrictedProfileParentId = parent.id;
+                            writeUserLP(parent);
                         }
-                    }
-                    mPm.createNewUserLILPw(userId);
-                    userInfo.partial = false;
-                    scheduleWriteUserLP(userInfo);
-                    updateUserIds();
-                    Bundle restrictions = new Bundle();
-                    synchronized (mRestrictionsLock) {
-                        mBaseUserRestrictions.append(userId, restrictions);
+                        userInfo.restrictedProfileParentId = parent.restrictedProfileParentId;
                     }
                 }
             }
-            mPm.newUserCreated(userId);
-            if (userInfo != null) {
-                Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
-                addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
-                mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
-                        android.Manifest.permission.MANAGE_USERS);
+            final StorageManager storage = mContext.getSystemService(StorageManager.class);
+            storage.createUserKey(userId, userInfo.serialNumber);
+            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+                final String volumeUuid = vol.getFsUuid();
+                try {
+                    final File userDir = Environment.getDataUserDirectory(volumeUuid, userId);
+                    storage.prepareUserStorage(volumeUuid, userId, userInfo.serialNumber);
+                    enforceSerialNumber(userDir, userInfo.serialNumber);
+                } catch (IOException e) {
+                    Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e);
+                }
             }
+            mPm.createNewUser(userId);
+            userInfo.partial = false;
+            synchronized (mPackagesLock) {
+                writeUserLP(userInfo);
+            }
+            updateUserIds();
+            Bundle restrictions = new Bundle();
+            synchronized (mRestrictionsLock) {
+                mBaseUserRestrictions.append(userId, restrictions);
+            }
+            mPm.newUserCreated(userId);
+            Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
+            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
+                    android.Manifest.permission.MANAGE_USERS);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -1738,11 +1760,7 @@
                                     // Clean up any ActivityManager state
                                     LocalServices.getService(ActivityManagerInternal.class)
                                             .onUserRemoved(userHandle);
-                                    synchronized (mInstallLock) {
-                                        synchronized (mPackagesLock) {
-                                            removeUserStateLILP(userHandle);
-                                        }
-                                    }
+                                    removeUserState(userHandle);
                                 }
                             }.start();
                         }
@@ -1754,11 +1772,10 @@
         }
     }
 
-    private void removeUserStateLILP(final int userHandle) {
-        mContext.getSystemService(StorageManager.class)
-            .deleteUserKey(userHandle);
+    private void removeUserState(final int userHandle) {
+        mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
         // Cleanup package manager settings
-        mPm.cleanUpUserLILPw(this, userHandle);
+        mPm.cleanUpUser(this, userHandle);
 
         // Remove this user from the list
         synchronized (mUsersLock) {
@@ -1768,7 +1785,9 @@
         AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
         userFile.delete();
         // Update the user list
-        writeUserListLILP();
+        synchronized (mPackagesLock) {
+            writeUserListLP();
+        }
         updateUserIds();
         removeDirectoryRecursive(Environment.getUserSystemDirectory(userHandle));
     }
@@ -2103,17 +2122,15 @@
      * @param userId the user that was just foregrounded
      */
     public void onUserForeground(int userId) {
-        synchronized (mPackagesLock) {
-            UserInfo user = getUserInfoNoChecks(userId);
-            long now = System.currentTimeMillis();
-            if (user == null || user.partial) {
-                Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
-                return;
-            }
-            if (now > EPOCH_PLUS_30_YEARS) {
-                user.lastLoggedInTime = now;
-                scheduleWriteUserLP(user);
-            }
+        UserInfo user = getUserInfoNoChecks(userId);
+        if (user == null || user.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);
         }
     }
 
@@ -2121,7 +2138,6 @@
      * Returns the next available user id, filling in any holes in the ids.
      * TODO: May not be a good idea to recycle ids, in case it results in confusion
      * for data and battery stats collection, or unexpected cross-talk.
-     * @return
      */
     private int getNextAvailableId() {
         synchronized (mUsersLock) {
@@ -2141,16 +2157,6 @@
     }
 
     /**
-     * Create new {@code /data/user/[id]} directory and sets default
-     * permissions.
-     */
-    public static void prepareUserDirectory(Context context, String volumeUuid, int userId) {
-        final StorageManager storage = context.getSystemService(StorageManager.class);
-        final File userDir = Environment.getDataUserDirectory(volumeUuid, userId);
-        storage.createNewUserDir(userId, userDir);
-    }
-
-    /**
      * Enforce that serial number stored in user directory inode matches the
      * given expected value. Gracefully sets the serial number if currently
      * undefined.
@@ -2247,7 +2253,7 @@
         } else {
             pw.println("Users:");
             for (int i = 0; i < users.size(); i++) {
-                String running = am.isUserRunning(users.get(i).id, false) ? " running" : "";
+                String running = am.isUserRunning(users.get(i).id, 0) ? " running" : "";
                 pw.println("\t" + users.get(i).toString() + running);
             }
             return 0;
@@ -2315,7 +2321,9 @@
             }
             pw.println();
             pw.println("Guest restrictions:");
-            UserRestrictionsUtils.dumpRestrictions(pw, "  ", mGuestRestrictions);
+            synchronized (mGuestRestrictions) {
+                UserRestrictionsUtils.dumpRestrictions(pw, "  ", mGuestRestrictions);
+            }
         }
     }
 
@@ -2388,6 +2396,25 @@
                 }
             }
         }
+
+        @Override
+        public boolean getUserRestriction(int userId, String key) {
+            return getUserRestrictions(userId).getBoolean(key);
+        }
+
+        @Override
+        public void addUserRestrictionsListener(UserRestrictionsListener listener) {
+            synchronized (mUserRestrictionsListeners) {
+                mUserRestrictionsListeners.add(listener);
+            }
+        }
+
+        @Override
+        public void removeUserRestrictionsListener(UserRestrictionsListener listener) {
+            synchronized (mUserRestrictionsListeners) {
+                mUserRestrictionsListeners.remove(listener);
+            }
+        }
     }
 
     private class Shell extends ShellCommand {
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 28df9f6..56e8b3e 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -18,19 +18,14 @@
 
 import com.google.android.collect.Sets;
 
-import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.media.IAudioService;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.util.Slog;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlSerializer;
@@ -39,6 +34,11 @@
 import java.io.PrintWriter;
 import java.util.Set;
 
+/**
+ * Utility methods for uesr restrictions.
+ *
+ * <p>See {@link UserManagerService} for the method suffixes.
+ */
 public class UserRestrictionsUtils {
     private static final String TAG = "UserRestrictionsUtils";
 
@@ -129,26 +129,31 @@
     /**
      * Takes a new use restriction set and the previous set, and apply the restrictions that have
      * changed.
+     *
+     * <p>Note this method is called by {@link UserManagerService} while holding
+     * {@code mRestrictionLock}. Be aware when calling into other services, which could cause
+     * a deadlock.
      */
-    public static void applyUserRestrictions(Context context, int userId,
-            @Nullable Bundle newRestrictions, @Nullable Bundle prevRestrictions) {
-        if (newRestrictions == null) {
-            newRestrictions = Bundle.EMPTY;
-        }
-        if (prevRestrictions == null) {
-            prevRestrictions = Bundle.EMPTY;
-        }
+    public static void applyUserRestrictionsLR(Context context, int userId,
+            Bundle newRestrictions, Bundle prevRestrictions) {
         for (String key : USER_RESTRICTIONS) {
             final boolean newValue = newRestrictions.getBoolean(key);
             final boolean prevValue = prevRestrictions.getBoolean(key);
 
             if (newValue != prevValue) {
-                applyUserRestriction(context, userId, key, newValue);
+                applyUserRestrictionLR(context, userId, key, newValue);
             }
         }
     }
 
-    private static void applyUserRestriction(Context context, int userId, String key,
+    /**
+     * Apply each user restriction.
+     *
+     * <p>Note this method is called by {@link UserManagerService} while holding
+     * {@code mRestrictionLock}. Be aware when calling into other services, which could cause
+     * a deadlock.
+     */
+    private static void applyUserRestrictionLR(Context context, int userId, String key,
             boolean newValue) {
         // When certain restrictions are cleared, we don't update the system settings,
         // because these settings are changeable on the Settings UI and we don't know the original
@@ -161,14 +166,6 @@
         final long id = Binder.clearCallingIdentity();
         try {
             switch (key) {
-                case UserManager.DISALLOW_UNMUTE_MICROPHONE:
-                    IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE))
-                            .setMicrophoneMute(newValue, context.getPackageName(), userId);
-                    break;
-                case UserManager.DISALLOW_ADJUST_VOLUME:
-                    IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE))
-                            .setMasterMute(newValue, 0, context.getPackageName(), userId);
-                    break;
                 case UserManager.DISALLOW_CONFIG_WIFI:
                     if (newValue) {
                         android.provider.Settings.Secure.putIntForUser(cr,
@@ -231,8 +228,6 @@
                     }
                     break;
             }
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Failed to talk to AudioService.", re);
         } finally {
             Binder.restoreCallingIdentity(id);
         }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 209751e..121ef21 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2532,6 +2532,12 @@
                     return R.anim.dock_right_enter;
                 }
             }
+        } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) {
+            if (transit == TRANSIT_ENTER) {
+                return R.anim.fade_in;
+            } else if (transit == TRANSIT_EXIT) {
+                return R.anim.fade_out;
+            }
         }
 
         if (transit == TRANSIT_PREVIEW_DONE) {
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index ac79b36..97713fc 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -54,6 +54,15 @@
                 @Override
                 public void onReceive(Context context, Intent intent) {
 
+                    // When a package is replaced we will receive two intents, one representing the
+                    // removal of the old package and one representing the addition of the new
+                    // package. We here ignore the intent representing the removed package to make
+                    // sure we don't change WebView provider twice.
+                    if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)
+                            && intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) {
+                        return;
+                    }
+
                     for (String packageName : WebViewFactory.getWebViewPackageNames()) {
                         String webviewPackage = "package:" + packageName;
 
@@ -73,7 +82,8 @@
                 }
         };
         IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         filter.addDataScheme("package");
         getContext().registerReceiver(mWebViewUpdatedReceiver, filter);
 
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 25a23fd..89f5658 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -49,9 +49,11 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
+import android.os.RemoteException;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.AppTransitionAnimationSpec;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
@@ -71,6 +73,8 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 // State management of app transitions.  When we are preparing for a
 // transition, mNextAppTransition will be the kind of transition to
@@ -160,6 +164,7 @@
     // Used for thumbnail transitions. True if we're scaling up, false if scaling down
     private boolean mNextAppTransitionScaleUp;
     private IRemoteCallback mNextAppTransitionCallback;
+    private IRemoteCallback mNextAppTransitionFutureCallback;
     private IRemoteCallback mAnimationFinishedCallback;
     private int mNextAppTransitionEnter;
     private int mNextAppTransitionExit;
@@ -168,6 +173,8 @@
     // Keyed by task id.
     private final SparseArray<AppTransitionAnimationSpec> mNextAppTransitionAnimationsSpecs
             = new SparseArray<>();
+    private IAppTransitionAnimationSpecsFuture mNextAppTransitionAnimationsSpecsFuture;
+    private boolean mNextAppTransitionAnimationsSpecsPending;
     private AppTransitionAnimationSpec mDefaultNextAppTransitionAnimationSpec;
 
     private Rect mNextAppTransitionInsets = new Rect();
@@ -200,10 +207,16 @@
     private int mCurrentUserId = 0;
 
     private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>();
+    private final ExecutorService mDefaultExecutor = Executors.newSingleThreadExecutor();
+    private final Object mServiceLock;
+    private final WindowSurfacePlacer mWindowSurfacePlacer;
 
-    AppTransition(Context context, Handler h) {
+    AppTransition(Context context, Handler h, Object serviceLock,
+            WindowSurfacePlacer windowSurfacePlacer) {
         mContext = context;
         mH = h;
+        mServiceLock = serviceLock;
+        mWindowSurfacePlacer = windowSurfacePlacer;
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.linear_out_slow_in);
         mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -262,6 +275,7 @@
 
     void setReady() {
         mAppTransitionState = APP_STATE_READY;
+        fetchAppTransitionSpecsFromFuture();
     }
 
     boolean isRunning() {
@@ -282,6 +296,9 @@
 
     Bitmap getAppTransitionThumbnailHeader(int taskId) {
         AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+        if (spec == null) {
+            spec = mDefaultNextAppTransitionAnimationSpec;
+        }
         return spec != null ? spec.bitmap : null;
     }
 
@@ -296,6 +313,14 @@
         return mNextAppTransitionScaleUp;
     }
 
+    /**
+     * @return true if and only if we are currently fetching app transition specs from the future
+     *         passed into {@link #overridePendingAppTransitionMultiThumbFuture}
+     */
+    boolean isFetchingAppTransitionsSpecs() {
+        return mNextAppTransitionAnimationsSpecsPending;
+    }
+
     private boolean prepare() {
         if (!isRunning()) {
             mAppTransitionState = APP_STATE_IDLE;
@@ -524,6 +549,9 @@
 
     void getNextAppTransitionStartRect(int taskId, Rect rect) {
         AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+        if (spec == null) {
+            spec = mDefaultNextAppTransitionAnimationSpec;
+        }
         if (spec == null || spec.rect == null) {
             Slog.wtf(TAG, "Starting rect for task: " + taskId + " requested, but not available",
                     new Throwable());
@@ -533,9 +561,10 @@
         }
     }
 
-    private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height) {
+    private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height,
+            Bitmap bitmap) {
         mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */,
-                null /* bitmap */, new Rect(left, top, left + width, top + height));
+                bitmap, new Rect(left, top, left + width, top + height));
     }
 
     private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame) {
@@ -1302,17 +1331,23 @@
         }
     }
 
+    private void clearAppTransitionState() {
+        mNextAppTransitionPackage = null;
+        mNextAppTransitionAnimationsSpecs.clear();
+        mDefaultNextAppTransitionAnimationSpec = null;
+        mAnimationFinishedCallback = null;
+    }
+
     void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
             IRemoteCallback startedCallback) {
         if (isTransitionSet()) {
+            clearAppTransitionState();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
             mNextAppTransitionPackage = packageName;
-            mNextAppTransitionAnimationsSpecs.clear();
             mNextAppTransitionEnter = enterAnim;
             mNextAppTransitionExit = exitAnim;
             postAnimationCallback();
             mNextAppTransitionCallback = startedCallback;
-            mAnimationFinishedCallback = null;
         } else {
             postAnimationCallback();
         }
@@ -1321,40 +1356,34 @@
     void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
             int startHeight) {
         if (isTransitionSet()) {
+            clearAppTransitionState();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
-            mNextAppTransitionPackage = null;
-            mNextAppTransitionAnimationsSpecs.clear();
             putDefaultNextAppTransitionCoordinates(startX, startY, startX + startWidth,
-                    startY + startHeight);
+                    startY + startHeight, null);
             postAnimationCallback();
-            mNextAppTransitionCallback = null;
-            mAnimationFinishedCallback = null;
         }
     }
 
     void overridePendingAppTransitionClipReveal(int startX, int startY,
                                                 int startWidth, int startHeight) {
         if (isTransitionSet()) {
+            clearAppTransitionState();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
-            putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight);
+            putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null);
             postAnimationCallback();
-            mNextAppTransitionCallback = null;
-            mAnimationFinishedCallback = null;
         }
     }
 
     void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
                                            IRemoteCallback startedCallback, boolean scaleUp) {
         if (isTransitionSet()) {
+            clearAppTransitionState();
             mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
                     : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
-            mNextAppTransitionPackage = null;
-            mNextAppTransitionAnimationsSpecs.clear();
             mNextAppTransitionScaleUp = scaleUp;
-            putDefaultNextAppTransitionCoordinates(startX, startY, 0 ,0);
+            putDefaultNextAppTransitionCoordinates(startX, startY, 0, 0, srcThumb);
             postAnimationCallback();
             mNextAppTransitionCallback = startedCallback;
-            mAnimationFinishedCallback = null;
         } else {
             postAnimationCallback();
         }
@@ -1363,15 +1392,14 @@
     void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY,
             int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
         if (isTransitionSet()) {
+            clearAppTransitionState();
             mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
                     : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
-            mNextAppTransitionPackage = null;
-            mNextAppTransitionAnimationsSpecs.clear();
             mNextAppTransitionScaleUp = scaleUp;
-            putDefaultNextAppTransitionCoordinates(startX, startY, targetWidth, targetHeight);
+            putDefaultNextAppTransitionCoordinates(startX, startY, targetWidth, targetHeight,
+                    srcThumb);
             postAnimationCallback();
             mNextAppTransitionCallback = startedCallback;
-            mAnimationFinishedCallback = null;
         } else {
             postAnimationCallback();
         }
@@ -1381,22 +1409,22 @@
             IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback,
             boolean scaleUp) {
         if (isTransitionSet()) {
+            clearAppTransitionState();
             mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
                     : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
-            mNextAppTransitionPackage = null;
-            mDefaultNextAppTransitionAnimationSpec = null;
-            mNextAppTransitionAnimationsSpecs.clear();
             mNextAppTransitionScaleUp = scaleUp;
-            for (int i = 0; i < specs.length; i++) {
-                AppTransitionAnimationSpec spec = specs[i];
-                if (spec != null) {
-                    mNextAppTransitionAnimationsSpecs.put(spec.taskId, spec);
-                    if (i == 0) {
-                        // In full screen mode, the transition code depends on the default spec to
-                        // be set.
-                        Rect rect = spec.rect;
-                        putDefaultNextAppTransitionCoordinates(rect.left, rect.top, rect.width(),
-                                rect.height());
+            if (specs != null) {
+                for (int i = 0; i < specs.length; i++) {
+                    AppTransitionAnimationSpec spec = specs[i];
+                    if (spec != null) {
+                        mNextAppTransitionAnimationsSpecs.put(spec.taskId, spec);
+                        if (i == 0) {
+                            // In full screen mode, the transition code depends on the default spec
+                            // to be set.
+                            Rect rect = spec.rect;
+                            putDefaultNextAppTransitionCoordinates(rect.left, rect.top,
+                                    rect.width(), rect.height(), null);
+                        }
                     }
                 }
             }
@@ -1408,17 +1436,61 @@
         }
     }
 
+    void overridePendingAppTransitionMultiThumbFuture(
+            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
+            boolean scaleUp) {
+        if (isTransitionSet()) {
+            clearAppTransitionState();
+            mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
+                    : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
+            mNextAppTransitionAnimationsSpecsFuture = specsFuture;
+            mNextAppTransitionScaleUp = scaleUp;
+            mNextAppTransitionFutureCallback = callback;
+        }
+    }
+
     void overrideInPlaceAppTransition(String packageName, int anim) {
         if (isTransitionSet()) {
+            clearAppTransitionState();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
             mNextAppTransitionPackage = packageName;
             mNextAppTransitionInPlace = anim;
-            mAnimationFinishedCallback = null;
         } else {
             postAnimationCallback();
         }
     }
 
+    /**
+     * If a future is set for the app transition specs, fetch it in another thread.
+     */
+    private void fetchAppTransitionSpecsFromFuture() {
+        if (mNextAppTransitionAnimationsSpecsFuture != null) {
+            mNextAppTransitionAnimationsSpecsPending = true;
+            final IAppTransitionAnimationSpecsFuture future
+                    = mNextAppTransitionAnimationsSpecsFuture;
+            mNextAppTransitionAnimationsSpecsFuture = null;
+            mDefaultExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    AppTransitionAnimationSpec[] specs = null;
+                    try {
+                        specs = future.get();
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Failed to fetch app transition specs: " + e);
+                    }
+                    synchronized (mServiceLock) {
+                        mNextAppTransitionAnimationsSpecsPending = false;
+                        overridePendingAppTransitionMultiThumb(specs,
+                                mNextAppTransitionFutureCallback, null /* finishedCallback */,
+                                mNextAppTransitionScaleUp);
+                        mNextAppTransitionFutureCallback = null;
+                        mWindowSurfacePlacer.requestTraversal();
+                    }
+                }
+            });
+        }
+    }
+
     @Override
     public String toString() {
         return "mNextAppTransition=" + appTransitionToString(mNextAppTransition);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 9143097..3f4eaac 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -128,11 +128,12 @@
     boolean mWillReplaceWindow;
     // If true, the replaced window was already requested to be removed.
     boolean mReplacingRemoveRequested;
-    // Whether the replacement of the window should trigger app transition animation.
-    boolean mAnimateReplacingWindow;
     // If not null, the window that will be used to replace the old one. This is being set when
     // the window is added and unset when this window reports its first draw.
     WindowState mReplacingWindow;
+    // Whether the new window has replaced the old one, so the old one can be removed without
+    // blinking.
+    boolean mHasReplacedWindow;
 
     AppWindowToken(WindowManagerService _service, IApplicationToken _token,
             boolean _voiceInteraction) {
@@ -189,7 +190,8 @@
                         + win.isDrawnLw()
                         + ", isAnimating=" + win.mWinAnimator.isAnimating());
                 if (!win.isDrawnLw()) {
-                    Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mWinAnimator.mSurfaceControl
+                    Slog.v(WindowManagerService.TAG, "Not displayed: s=" +
+                            win.mWinAnimator.mSurfaceController
                             + " pv=" + win.mPolicyVisibility
                             + " mDrawState=" + win.mWinAnimator.mDrawState
                             + " ah=" + win.mAttachedHidden
@@ -274,11 +276,11 @@
             // If we're animating with a saved surface, we're already visible.
             // Return true so that the alpha doesn't get cleared.
             if (!win.mAppFreezing
-                    && (win.mViewVisibility == View.VISIBLE
-                    || mAnimatingWithSavedSurface
-                    || (win.mWinAnimator.isAnimating() &&
-                            !service.mAppTransition.isTransitionSet()))
-                    && !win.mDestroying && win.isDrawnLw()) {
+                    && (win.mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface
+                            || (win.mWinAnimator.isAnimating()
+                                    && !service.mAppTransition.isTransitionSet()))
+                    && !win.mDestroying
+                    && win.isDrawnLw()) {
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 5aa266d..7b08354 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -45,7 +45,7 @@
             int h = b-t;
 
             if (WindowManagerService.DEBUG_SURFACE_TRACE) {
-                surface = new WindowStateAnimator.SurfaceTrace(session, "BlackSurface("
+                surface = new WindowSurfaceController.SurfaceTrace(session, "BlackSurface("
                         + l + ", " + t + ")",
                         w, h, PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
             } else {
diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java
index be3e922..33cec64 100644
--- a/services/core/java/com/android/server/wm/CircularDisplayMask.java
+++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java
@@ -65,7 +65,7 @@
         SurfaceControl ctrl = null;
         try {
             if (WindowManagerService.DEBUG_SURFACE_TRACE) {
-                ctrl = new WindowStateAnimator.SurfaceTrace(session, "CircularDisplayMask",
+                ctrl = new WindowSurfaceController.SurfaceTrace(session, "CircularDisplayMask",
                         mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
                         SurfaceControl.HIDDEN);
             } else {
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index bc31274..4b3620f 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -70,7 +70,7 @@
         /** Returns the display info. of the dim layer user. */
         DisplayInfo getDisplayInfo();
         /** Gets the bounds of the dim layer user. */
-        void getBounds(Rect outBounds);
+        void getDimBounds(Rect outBounds);
         String toShortString();
     }
     /** The user of this dim layer. */
@@ -82,7 +82,7 @@
         SurfaceControl.openTransaction();
         try {
             if (WindowManagerService.DEBUG_SURFACE_TRACE) {
-                mDimSurface = new WindowStateAnimator.SurfaceTrace(service.mFxSession,
+                mDimSurface = new WindowSurfaceController.SurfaceTrace(service.mFxSession,
                     "DimSurface",
                     16, 16, PixelFormat.OPAQUE,
                     SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index baf8b62..bd30bd5 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -43,7 +43,7 @@
 
     /** Updates the dim layer bounds, recreating it if needed. */
     void updateDimLayer(DimLayer.DimLayerUser dimLayerUser) {
-        DimLayerState state = getOrCreateDimLayerState(dimLayerUser, false);
+        DimLayerState state = getOrCreateDimLayerState(dimLayerUser);
         final boolean previousFullscreen = state.dimLayer != null
                 && state.dimLayer == mSharedFullScreenDimLayer;
         DimLayer newDimLayer;
@@ -63,7 +63,7 @@
                     // Create new full screen dim layer.
                     newDimLayer = new DimLayer(mDisplayContent.mService, dimLayerUser, displayId);
                 }
-                dimLayerUser.getBounds(mTmpBounds);
+                dimLayerUser.getDimBounds(mTmpBounds);
                 newDimLayer.setBounds(mTmpBounds);
                 mSharedFullScreenDimLayer = newDimLayer;
             } else if (state.dimLayer != null) {
@@ -73,14 +73,13 @@
             newDimLayer = (state.dimLayer == null || previousFullscreen)
                     ? new DimLayer(mDisplayContent.mService, dimLayerUser, displayId)
                     : state.dimLayer;
-            dimLayerUser.getBounds(mTmpBounds);
+            dimLayerUser.getDimBounds(mTmpBounds);
             newDimLayer.setBounds(mTmpBounds);
         }
         state.dimLayer = newDimLayer;
     }
 
-    private DimLayerState getOrCreateDimLayerState(
-            DimLayer.DimLayerUser dimLayerUser, boolean aboveApp) {
+    private DimLayerState getOrCreateDimLayerState(DimLayer.DimLayerUser dimLayerUser) {
         if (DEBUG_DIM_LAYER) Slog.v(TAG, "getOrCreateDimLayerState, dimLayerUser="
                 + dimLayerUser.toShortString());
         DimLayerState state = mState.get(dimLayerUser);
@@ -88,7 +87,6 @@
             state = new DimLayerState();
             mState.put(dimLayerUser, state);
         }
-        state.dimAbove = aboveApp;
         return state;
     }
 
@@ -127,13 +125,14 @@
             WindowStateAnimator newWinAnimator, boolean aboveApp) {
         // Only set dim params on the highest dimmed layer.
         // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
-        DimLayerState state = getOrCreateDimLayerState(dimLayerUser, aboveApp);
+        DimLayerState state = getOrCreateDimLayerState(dimLayerUser);
+        state.dimAbove = aboveApp;
         if (DEBUG_DIM_LAYER) Slog.v(TAG, "startDimmingIfNeeded,"
                 + " dimLayerUser=" + dimLayerUser.toShortString()
                 + " newWinAnimator=" + newWinAnimator
                 + " state.animator=" + state.animator);
-        if (newWinAnimator.mSurfaceShown && (state.animator == null
-                || !state.animator.mSurfaceShown
+        if (newWinAnimator.getShown() && (state.animator == null
+                || !state.animator.getShown()
                 || state.animator.mAnimLayer <= newWinAnimator.mAnimLayer)) {
             state.animator = newWinAnimator;
             if (state.animator.mWin.mAppToken == null && !dimLayerUser.isFullscreen()) {
@@ -161,7 +160,7 @@
                 + " state.dimLayer.isDimming=" + state.dimLayer.isDimming());
         if (!state.continueDimming && state.dimLayer.isDimming()) {
             state.animator = null;
-            dimLayerUser.getBounds(mTmpBounds);
+            dimLayerUser.getDimBounds(mTmpBounds);
             state.dimLayer.setBounds(mTmpBounds);
         }
     }
@@ -270,7 +269,14 @@
     }
 
     void removeDimLayerUser(DimLayer.DimLayerUser dimLayerUser) {
-        mState.remove(dimLayerUser);
+        DimLayerState state = mState.get(dimLayerUser);
+        if (state != null) {
+            // Destroy the surface, unless it's the shared fullscreen dim.
+            if (state.dimLayer != mSharedFullScreenDimLayer) {
+                state.dimLayer.destroySurface();
+            }
+            mState.remove(dimLayerUser);
+        }
     }
 
     void applyDimBehind(DimLayer.DimLayerUser dimLayerUser, WindowStateAnimator animator) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 53f8bbd..328c043 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -22,7 +22,6 @@
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerService.TAG;
 import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
-import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
 
 import android.app.ActivityManager.StackId;
 import android.graphics.Rect;
@@ -55,17 +54,6 @@
      * from mDisplayWindows; */
     private final WindowList mWindows = new WindowList();
 
-    // This protects the following display size properties, so that
-    // getDisplaySize() doesn't need to acquire the global lock.  This is
-    // needed because the window manager sometimes needs to use ActivityThread
-    // while it has its global state locked (for example to load animation
-    // resources), but the ActivityThread also needs get the current display
-    // size sometimes when it has its package lock held.
-    //
-    // These will only be modified with both mWindowMap and mDisplaySizeLock
-    // held (in that order) so the window manager doesn't need to acquire this
-    // lock when needing these values in its normal operation.
-    final Object mDisplaySizeLock = new Object();
     int mInitialDisplayWidth = 0;
     int mInitialDisplayHeight = 0;
     int mInitialDisplayDensity = 0;
@@ -154,6 +142,10 @@
         return mDisplayMetrics;
     }
 
+    DockedStackDividerController getDockedDividerController() {
+        return mDividerControllerLocked;
+    }
+
     /**
      * Returns true if the specified UID has access to this display.
      */
@@ -192,25 +184,22 @@
     void updateDisplayInfo() {
         mDisplay.getDisplayInfo(mDisplayInfo);
         mDisplay.getMetrics(mDisplayMetrics);
-        mDividerControllerLocked.updateDisplayInfo();
         for (int i = mStacks.size() - 1; i >= 0; --i) {
             mStacks.get(i).updateDisplayInfo(null);
         }
     }
 
     void initializeDisplayBaseInfo() {
-        synchronized(mDisplaySizeLock) {
-            // Bootstrap the default logical display from the display manager.
-            final DisplayInfo newDisplayInfo =
-                    mService.mDisplayManagerInternal.getDisplayInfo(mDisplayId);
-            if (newDisplayInfo != null) {
-                mDisplayInfo.copyFrom(newDisplayInfo);
-            }
-            mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
-            mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
-            mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
-            mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
+        // Bootstrap the default logical display from the display manager.
+        final DisplayInfo newDisplayInfo =
+                mService.mDisplayManagerInternal.getDisplayInfo(mDisplayId);
+        if (newDisplayInfo != null) {
+            mDisplayInfo.copyFrom(newDisplayInfo);
         }
+        mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
+        mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
+        mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
+        mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
     }
 
     void getLogicalDisplayRect(Rect out) {
@@ -288,16 +277,18 @@
             final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
             for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
                 final Task task = tasks.get(taskNdx);
-                // We need to use the visible frame on the window for any touch-related tests.
-                // Can't use the task's bounds because the original task bounds might be adjusted
-                // to fit the content frame. For example, the presence of the IME adjusting the
+                final WindowState win = task.getTopVisibleAppMainWindow();
+                if (win == null) {
+                    continue;
+                }
+                // We need to use the task's dim bounds (which is derived from the visible
+                // bounds of its apps windows) for any touch-related tests. Can't use
+                // the task's original bounds because it might be adjusted to fit the
+                // content frame. For example, the presence of the IME adjusting the
                 // windows frames when the app window is the IME target.
-                final WindowState win = task.getTopAppMainWindow();
-                if (win != null) {
-                    win.getVisibleBounds(mTmpRect, !BOUNDS_FOR_TOUCH);
-                    if (mTmpRect.contains(x, y)) {
-                        return task.mTaskId;
-                    }
+                task.getDimBounds(mTmpRect);
+                if (mTmpRect.contains(x, y)) {
+                    return task.mTaskId;
                 }
             }
         }
@@ -305,10 +296,10 @@
     }
 
     /**
-     * Find the window whose outside touch area (for resizing) (x, y) falls within.
+     * Find the task whose outside touch area (for resizing) (x, y) falls within.
      * Returns null if the touch doesn't fall into a resizing area.
      */
-    WindowState findWindowForControlPoint(int x, int y) {
+    Task findTaskForControlPoint(int x, int y) {
         final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             TaskStack stack = mStacks.get(stackNdx);
@@ -322,24 +313,22 @@
                     return null;
                 }
 
-                // We need to use the visible frame on the window for any touch-related
-                // tests. Can't use the task's bounds because the original task bounds
-                // might be adjusted to fit the content frame. (One example is when the
-                // task is put to top-left quadrant, the actual visible frame would not
-                // start at (0,0) after it's adjusted for the status bar.)
-                final WindowState win = task.getTopAppMainWindow();
-                if (win != null) {
-                    win.getVisibleBounds(mTmpRect, !BOUNDS_FOR_TOUCH);
-                    mTmpRect.inset(-delta, -delta);
-                    if (mTmpRect.contains(x, y)) {
-                        mTmpRect.inset(delta, delta);
-                        if (!mTmpRect.contains(x, y)) {
-                            return win;
-                        }
-                        // User touched inside the task. No need to look further,
-                        // focus transfer will be handled in ACTION_UP.
-                        return null;
+                // We need to use the task's dim bounds (which is derived from the visible
+                // bounds of its apps windows) for any touch-related tests. Can't use
+                // the task's original bounds because it might be adjusted to fit the
+                // content frame. One example is when the task is put to top-left quadrant,
+                // the actual visible area would not start at (0,0) after it's adjusted
+                // for the status bar.
+                task.getDimBounds(mTmpRect);
+                mTmpRect.inset(-delta, -delta);
+                if (mTmpRect.contains(x, y)) {
+                    mTmpRect.inset(delta, delta);
+                    if (!mTmpRect.contains(x, y)) {
+                        return task;
                     }
+                    // User touched inside the task. No need to look further,
+                    // focus transfer will be handled in ACTION_UP.
+                    return null;
                 }
             }
         }
@@ -348,12 +337,18 @@
 
     void setTouchExcludeRegion(Task focusedTask) {
         mTouchExcludeRegion.set(mBaseDisplayRect);
-        WindowList windows = getWindowList();
         final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
-        for (int i = windows.size() - 1; i >= 0; --i) {
-            final WindowState win = windows.get(i);
-            final Task task = win.getTask();
-            if (win.isVisibleLw() && task != null) {
+        boolean addBackFocusedTask = false;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            TaskStack stack = mStacks.get(stackNdx);
+            final ArrayList<Task> tasks = stack.getTasks();
+            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                final Task task = tasks.get(taskNdx);
+                final WindowState win = task.getTopVisibleAppMainWindow();
+                if (win == null) {
+                    continue;
+                }
+
                 /**
                  * Exclusion region is the region that TapDetector doesn't care about.
                  * Here we want to remove all non-focused tasks from the exclusion region.
@@ -365,28 +360,35 @@
                  */
                 final boolean isFreeformed = task.inFreeformWorkspace();
                 if (task != focusedTask || isFreeformed) {
-                    mTmpRect.set(win.mVisibleFrame);
-                    mTmpRect.intersect(win.mVisibleInsets);
-                    /**
-                     * If the task is freeformed, enlarge the area to account for outside
-                     * touch area for resize.
-                     */
+                    task.getDimBounds(mTmpRect);
                     if (isFreeformed) {
+                        // If we're removing a freeform, focused app from the exclusion region,
+                        // we need to add back its touchable frame later. Remember the touchable
+                        // frame now.
+                        if (task == focusedTask) {
+                            addBackFocusedTask = true;
+                            mTmpRect2.set(mTmpRect);
+                        }
+                        // If the task is freeformed, enlarge the area to account for outside
+                        // touch area for resize.
                         mTmpRect.inset(-delta, -delta);
+                        // Intersect with display content rect. If we have system decor (status bar/
+                        // navigation bar), we want to exclude that from the tap detection.
+                        // Otherwise, if the app is partially placed under some system button (eg.
+                        // Recents, Home), pressing that button would cause a full series of
+                        // unwanted transfer focus/resume/pause, before we could go home.
+                        mTmpRect.intersect(mContentRect);
                     }
                     mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
                 }
-                /**
-                 * If we removed the focused task above, add it back and only leave its
-                 * outside touch area in the exclusion. TapDectector is not interested in
-                 * any touch inside the focused task itself.
-                 */
-                if (task == focusedTask && isFreeformed) {
-                    mTmpRect.inset(delta, delta);
-                    mTouchExcludeRegion.op(mTmpRect, Region.Op.UNION);
-                }
             }
         }
+        // If we removed the focused task above, add it back and only leave its
+        // outside touch area in the exclusion. TapDectector is not interested in
+        // any touch inside the focused task itself.
+        if (addBackFocusedTask) {
+            mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
+        }
         if (mTapDetector != null) {
             mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
         }
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index eafc3c6..6b62467 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -16,122 +16,64 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.view.PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW;
-import static android.view.PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
-import static android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING;
-import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-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.TaskPositioner.SIDE_MARGIN_DIP;
-import static com.android.server.wm.TaskStack.DOCKED_BOTTOM;
-import static com.android.server.wm.TaskStack.DOCKED_LEFT;
-import static com.android.server.wm.TaskStack.DOCKED_RIGHT;
-import static com.android.server.wm.TaskStack.DOCKED_TOP;
-import static com.android.server.wm.WindowManagerService.dipToPixel;
-
 import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.PixelFormat;
 import android.graphics.Rect;
-import android.os.RemoteException;
 import android.util.Slog;
-import android.view.DisplayInfo;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
+
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+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;
 
 /**
- * Controls showing and hiding of a docked stack divider on the display.
+ * Keeps information about the docked stack divider.
  */
-public class DockedStackDividerController implements View.OnTouchListener, DimLayer.DimLayerUser {
-    private static final String TAG = "DockedStackDivider";
-    private final Context mContext;
-    private final int mDividerWidth;
+public class DockedStackDividerController {
+
+    private static final String TAG = "DockedStackDividerController";
+
     private final DisplayContent mDisplayContent;
-    private final int mSideMargin;
-    private final DimLayer mDimLayer;
-    private int mDisplayWidth;
-    private int mDisplayHeight;
-    private View mView;
-    private Rect mTmpRect = new Rect();
-    private Rect mLastResizeRect = new Rect();
-    private int mStartX;
-    private int mStartY;
-    private TaskStack mTaskStack;
-    private Rect mOriginalRect = new Rect();
-    private int mDockSide;
-    private boolean mDimLayerVisible;
+    private final int mDividerWindowWidth;
+    private final int mDividerInsets;
+    private boolean mResizing;
+    private WindowState mWindow;
+    private final Rect mTmpRect = new Rect();
+    private final Rect mLastRect = new Rect();
 
     DockedStackDividerController(Context context, DisplayContent displayContent) {
-        mContext = context;
         mDisplayContent = displayContent;
-        updateDisplayInfo();
-        mDividerWidth = context.getResources().getDimensionPixelSize(
+        mDividerWindowWidth = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_thickness);
-        mSideMargin = dipToPixel(SIDE_MARGIN_DIP, mDisplayContent.getDisplayMetrics());
-        mDimLayer = new DimLayer(displayContent.mService, this, displayContent.getDisplayId());
+        mDividerInsets = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_insets);
     }
 
-    private void addDivider(Configuration configuration) {
-        View view = LayoutInflater.from(mContext).inflate(
-                com.android.internal.R.layout.docked_stack_divider, null);
-        view.setOnTouchListener(this);
-        WindowManagerGlobal manager = WindowManagerGlobal.getInstance();
-        final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
-        final int width = landscape ? mDividerWidth : MATCH_PARENT;
-        final int height = landscape ? MATCH_PARENT : mDividerWidth;
-        view.setPointerShape(
-                landscape ? STYLE_HORIZONTAL_DOUBLE_ARROW : STYLE_VERTICAL_DOUBLE_ARROW);
-        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
-                width, height, TYPE_DOCK_DIVIDER,
-                FLAG_TOUCHABLE_WHEN_WAKING | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL
-                        | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH,
-                PixelFormat.OPAQUE);
-        params.setTitle(TAG);
-        manager.addView(view, params, mDisplayContent.getDisplay(), null);
-        mView = view;
+    boolean isResizing() {
+        return mResizing;
     }
 
-    private void removeDivider() {
-        mView.setOnTouchListener(null);
-        WindowManagerGlobal manager = WindowManagerGlobal.getInstance();
-        manager.removeView(mView, true /* immediate */);
-        mView = null;
+    int getContentWidth() {
+        return mDividerWindowWidth - 2 * mDividerInsets;
     }
 
-    boolean hasDivider() {
-        return mView != null;
+    void setResizing(boolean resizing) {
+        mResizing = resizing;
     }
 
-    void updateDisplayInfo() {
-        final DisplayInfo info = mDisplayContent.getDisplayInfo();
-        mDisplayWidth = info.logicalWidth;
-        mDisplayHeight = info.logicalHeight;
+    void setWindow(WindowState window) {
+        mWindow = window;
+        reevaluateVisibility();
     }
 
-    void update(Configuration configuration, boolean forceUpdate) {
-        if (forceUpdate && mView != null) {
-            removeDivider();
+    void reevaluateVisibility() {
+        if (mWindow == null) return;
+        TaskStack stack = mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID);
+        if (stack != null && stack.isVisibleLocked()) {
+            mWindow.showLw(true /* doAnimation */);
+        } else {
+            mWindow.hideLw(true /* doAnimation */);
         }
-        TaskStack stack = mDisplayContent.getDockedStackLocked();
-        if (stack != null && mView == null) {
-            addDivider(configuration);
-        } else if (stack == null && mView != null) {
-            removeDivider();
-        }
-    }
-
-    int getWidth() {
-        return mDividerWidth;
     }
 
     void positionDockedStackedDivider(Rect frame) {
@@ -139,268 +81,33 @@
         if (stack == null) {
             // Unfortunately we might end up with still having a divider, even though the underlying
             // stack was already removed. This is because we are on AM thread and the removal of the
-            // divider was deferred to WM thread and hasn't happened yet.
+            // divider was deferred to WM thread and hasn't happened yet. In that case let's just
+            // keep putting it in the same place it was before the stack was removed to have
+            // continuity and prevent it from jumping to the center. It will get hidden soon.
+            frame.set(mLastRect);
             return;
+        } else {
+            stack.getDimBounds(mTmpRect);
         }
-        final @TaskStack.DockSide int side = stack.getDockSide();
-        stack.getBounds(mTmpRect);
+        int side = stack.getDockSide();
         switch (side) {
             case DOCKED_LEFT:
-                frame.set(mTmpRect.right, frame.top, mTmpRect.right + frame.width(), frame.bottom);
+                frame.set(mTmpRect.right - mDividerInsets, frame.top,
+                        mTmpRect.right + frame.width() - mDividerInsets, frame.bottom);
                 break;
             case DOCKED_TOP:
-                frame.set(frame.left, mTmpRect.bottom, mTmpRect.right,
-                        mTmpRect.bottom + frame.height());
+                frame.set(frame.left, mTmpRect.bottom - mDividerInsets,
+                        mTmpRect.right, mTmpRect.bottom + frame.height() - mDividerInsets);
                 break;
             case DOCKED_RIGHT:
-                frame.set(mTmpRect.left - frame.width(), frame.top, mTmpRect.left, frame.bottom);
+                frame.set(mTmpRect.left - frame.width() + mDividerInsets, frame.top,
+                        mTmpRect.left + mDividerInsets, frame.bottom);
                 break;
             case DOCKED_BOTTOM:
-                frame.set(frame.left, mTmpRect.top - frame.height(), frame.right, mTmpRect.top);
+                frame.set(frame.left, mTmpRect.top - frame.height() + mDividerInsets,
+                        frame.right, mTmpRect.top + mDividerInsets);
                 break;
         }
-    }
-
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        final int action = event.getAction() & MotionEvent.ACTION_MASK;
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                // We use raw values, because getX/Y() would give us results relative to the
-                // dock divider bounds.
-                mStartX = (int) event.getRawX();
-                mStartY = (int) event.getRawY();
-                synchronized (mDisplayContent.mService.mWindowMap) {
-                    mTaskStack = mDisplayContent.getDockedStackLocked();
-                    if (mTaskStack != null) {
-                        mTaskStack.getBounds(mOriginalRect);
-                        mDockSide = mTaskStack.getDockSide();
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_MOVE:
-                if (mTaskStack != null) {
-                    final int x = (int) event.getRawX();
-                    final int y = (int) event.getRawY();
-                    resizeStack(x, y);
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                if (mTaskStack != null) {
-                    final int x = (int) event.getRawX();
-                    final int y = (int) event.getRawY();
-                    // At most one of these will be executed, the other one will exit early.
-                    maybeDismissTaskStack(x, y);
-                    maybeMaximizeTaskStack(x, y);
-                    mTaskStack = null;
-                }
-                setDimLayerVisible(false);
-                mDockSide = TaskStack.DOCKED_INVALID;
-                break;
-        }
-        return true;
-    }
-
-    private void maybeMaximizeTaskStack(int x, int y) {
-        final int distance = distanceFromFullScreen(mDockSide, x, y);
-        if (distance == -1) {
-            Slog.wtf(TAG, "maybeMaximizeTaskStack: Unknown dock side=" + mDockSide);
-            return;
-        }
-        if (distance <= mSideMargin) {
-            try {
-                mDisplayContent.mService.mActivityManager.resizeStack(
-                        mTaskStack.mStackId, null, true);
-            } catch (RemoteException e) {
-                // This can't happen because we are in the same process.
-            }
-        }
-    }
-
-    private void maybeDismissTaskStack(int x, int y) {
-        final int distance = distanceFromDockSide(mDockSide, mOriginalRect, x, y);
-        if (distance == -1) {
-            Slog.wtf(TAG, "maybeDismissTaskStack: Unknown dock side=" + mDockSide);
-            return;
-        }
-        if (distance <= mSideMargin) {
-            try {
-                mDisplayContent.mService.mActivityManager.removeStack(mTaskStack.mStackId);
-            } catch (RemoteException e) {
-                // This can't happen because we are in the same process.
-            }
-        }
-    }
-
-    private void updateDimLayer(int x, int y) {
-        final int dismissDistance = distanceFromDockSide(mDockSide, mOriginalRect, x, y);
-        final int maximizeDistance = distanceFromFullScreen(mDockSide, x, y);
-        if (dismissDistance == -1 || maximizeDistance == -1) {
-            Slog.wtf(TAG, "updateDimLayer: Unknown dock side=" + mDockSide);
-            return;
-        }
-        if (dismissDistance <= mSideMargin && maximizeDistance <= mSideMargin) {
-            Slog.wtf(TAG, "Both dismiss and maximize distances would trigger dim layer.");
-            return;
-        }
-        if (dismissDistance <= mSideMargin) {
-            setDismissDimLayerVisible(x, y);
-        } else if (maximizeDistance <= mSideMargin) {
-            setMaximizeDimLayerVisible(x, y);
-        } else {
-            setDimLayerVisible(false);
-        }
-    }
-
-    /**
-     * Provides the distance from the point to the docked side of a rectangle.
-     *
-     * @return non negative distance or -1 on error
-     */
-    private static int distanceFromDockSide(int dockSide, Rect bounds, int x, int y) {
-        switch (dockSide) {
-            case DOCKED_LEFT:
-                return x - bounds.left;
-            case DOCKED_TOP:
-                return y - bounds.top;
-            case DOCKED_RIGHT:
-                return bounds.right - x;
-            case DOCKED_BOTTOM:
-                return bounds.bottom - y;
-        }
-        return -1;
-    }
-
-    private int distanceFromFullScreen(int dockSide, int x, int y) {
-        switch (dockSide) {
-            case DOCKED_LEFT:
-                return mDisplayWidth - x;
-            case DOCKED_TOP:
-                return mDisplayHeight - y;
-            case DOCKED_RIGHT:
-                return x;
-            case DOCKED_BOTTOM:
-                return y;
-        }
-        return -1;
-    }
-
-    private void setDismissDimLayerVisible(int x, int y) {
-        mTmpRect.set(mOriginalRect);
-        switch (mDockSide) {
-            case DOCKED_LEFT:
-                mTmpRect.right = x;
-                break;
-            case DOCKED_TOP:
-                mTmpRect.bottom = y;
-                break;
-            case DOCKED_RIGHT:
-                mTmpRect.left = x;
-                break;
-            case DOCKED_BOTTOM:
-                mTmpRect.top = y;
-                break;
-            default:
-                Slog.wtf(TAG, "setDismissDimLayerVisible: Unknown dock side when setting dim "
-                        + "layer=" + mDockSide);
-                return;
-        }
-        mDimLayer.setBounds(mTmpRect);
-        setDimLayerVisible(true);
-    }
-
-    private void setMaximizeDimLayerVisible(int x, int y) {
-        mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight);
-        switch (mDockSide) {
-            case DOCKED_LEFT:
-                mTmpRect.left = x;
-                break;
-            case DOCKED_TOP:
-                mTmpRect.top = y;
-                break;
-            case DOCKED_RIGHT:
-                mTmpRect.right = x;
-                break;
-            case DOCKED_BOTTOM:
-                mTmpRect.top = y;
-                break;
-            default:
-                Slog.wtf(TAG, "setMaximizeDimLayerVisible: Unknown dock side when setting dim "
-                        + "layer=" + mDockSide);
-        }
-        mDimLayer.setBounds(mTmpRect);
-        setDimLayerVisible(true);
-    }
-
-    private void setDimLayerVisible(boolean visible) {
-        if (mDimLayerVisible == visible) {
-            return;
-        }
-        mDimLayerVisible = visible;
-        if (mDimLayerVisible) {
-            mDimLayer.show(mDisplayContent.mService.getDragLayerLocked(), RESIZING_HINT_ALPHA,
-                    RESIZING_HINT_DURATION_MS);
-        } else {
-            mDimLayer.hide();
-        }
-    }
-
-    private void resizeStack(int x, int y) {
-        mTmpRect.set(mOriginalRect);
-        final int deltaX = x - mStartX;
-        final int deltaY = y - mStartY;
-        switch (mDockSide) {
-            case DOCKED_LEFT:
-                mTmpRect.right += deltaX;
-                break;
-            case DOCKED_TOP:
-                mTmpRect.bottom += deltaY;
-                break;
-            case DOCKED_RIGHT:
-                mTmpRect.left += deltaX;
-                break;
-            case DOCKED_BOTTOM:
-                mTmpRect.top += deltaY;
-                break;
-        }
-        if (mTmpRect.equals(mLastResizeRect)) {
-            return;
-        }
-        mLastResizeRect.set(mTmpRect);
-        try {
-            mDisplayContent.mService.mActivityManager.resizeStack(DOCKED_STACK_ID, mTmpRect, true);
-        } catch (RemoteException e) {
-            // This can't happen because we are in the same process.
-        }
-        updateDimLayer(x, y);
-    }
-
-    boolean isResizing() {
-        return mTaskStack != null;
-    }
-
-    int getWidthAdjustment() {
-        return getWidth() / 2;
-    }
-
-    @Override
-    public boolean isFullscreen() {
-        return false;
-    }
-
-    @Override
-    public DisplayInfo getDisplayInfo() {
-        return mDisplayContent.getDisplayInfo();
-    }
-
-    @Override
-    public void getBounds(Rect outBounds) {
-        // This dim layer user doesn't need this.
-    }
-
-    @Override
-    public String toShortString() {
-        return TAG;
+        mLastRect.set(frame);
     }
 }
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index f35ea66..4926352 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.input.InputWindowHandle;
 import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
@@ -27,7 +26,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.os.Binder;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Process;
@@ -52,6 +50,7 @@
     SurfaceControl mSurfaceControl;
     int mFlags;
     IBinder mLocalWin;
+    int mPid;
     int mUid;
     ClipData mData;
     ClipDescription mDataDescription;
@@ -270,8 +269,15 @@
             Slog.d(WindowManagerService.TAG, "broadcasting DRAG_ENDED");
         }
         for (WindowState ws : mNotifiedWindows) {
+            float x = 0;
+            float y = 0;
+            if (!mDragResult && (ws.mSession.mPid == mPid)) {
+                // Report unconsumed drop location back to the app that started the drag.
+                x = mCurrentX;
+                y = mCurrentY;
+            }
             DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
-                    0, 0, null, null, null, null, mDragResult);
+                    x, y, null, null, null, null, mDragResult);
             try {
                 ws.mClient.dispatchDragEvent(evt);
             } catch (RemoteException e) {
@@ -428,7 +434,7 @@
                 continue;
             }
 
-            child.getVisibleBounds(mTmpRect, !BOUNDS_FOR_TOUCH);
+            child.getVisibleBounds(mTmpRect);
             if (!mTmpRect.contains(x, y)) {
                 // outside of this window's activity stack == don't tell about drags
                 continue;
diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
index 4c8a6f9..0a372d8 100644
--- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
+++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
@@ -54,7 +54,7 @@
         SurfaceControl ctrl = null;
         try {
             if (WindowManagerService.DEBUG_SURFACE_TRACE) {
-                ctrl = new WindowStateAnimator.SurfaceTrace(session, "EmulatorDisplayOverlay",
+                ctrl = new WindowSurfaceController.SurfaceTrace(session, "EmulatorDisplayOverlay",
                         mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
                         SurfaceControl.HIDDEN);
             } else {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index f999402..1f351cb 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -171,10 +171,10 @@
 
     private void addInputWindowHandleLw(final InputWindowHandle inputWindowHandle,
             final WindowState child, int flags, final int type, final boolean isVisible,
-            final boolean hasFocus, final boolean hasWallpaper, DisplayContent displayContent) {
+            final boolean hasFocus, final boolean hasWallpaper) {
         // Add a window to our list of input windows.
         inputWindowHandle.name = child.toString();
-        flags = child.getTouchableRegion(inputWindowHandle.touchableRegion, flags, this);
+        flags = child.getTouchableRegion(inputWindowHandle.touchableRegion, flags);
         inputWindowHandle.layoutParamsFlags = flags;
         inputWindowHandle.layoutParamsType = type;
         inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
@@ -193,20 +193,6 @@
         inputWindowHandle.frameTop = frame.top;
         inputWindowHandle.frameRight = frame.right;
         inputWindowHandle.frameBottom = frame.bottom;
-        if (child.mAttrs.type == TYPE_DOCK_DIVIDER) {
-            // We need to determine if the divider is horizontal or vertical and adjust its handle
-            // frame accordingly.
-            int adjustment = displayContent.mDividerControllerLocked.getWidthAdjustment();
-            if (inputWindowHandle.frameRight - inputWindowHandle.frameLeft >
-                    inputWindowHandle.frameTop - inputWindowHandle.frameBottom) {
-                // Horizontal divider.
-                inputWindowHandle.frameTop -= adjustment;
-                inputWindowHandle.frameBottom += adjustment;
-            } else {
-                inputWindowHandle.frameLeft -= adjustment;
-                inputWindowHandle.frameRight += adjustment;
-            }
-        }
 
         if (child.mGlobalScale != 1) {
             // If we are scaling the window, input coordinates need
@@ -322,8 +308,8 @@
                     mService.mDragState.sendDragStartedIfNeededLw(child);
                 }
 
-                addInputWindowHandleLw(inputWindowHandle, child, flags, type, isVisible, hasFocus,
-                        hasWallpaper, displayContent);
+                addInputWindowHandleLw(
+                        inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 283d498..3158c47 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -19,7 +19,7 @@
 import java.io.PrintWriter;
 
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
-import static com.android.server.wm.WindowStateAnimator.SurfaceTrace;
+import static com.android.server.wm.WindowSurfaceController.SurfaceTrace;
 import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
 import android.content.Context;
 import android.graphics.Matrix;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index c47c377..1caeca0 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -188,9 +188,10 @@
     }
 
     @Override
-    public void repositionChild(IWindow window, int x, int y, long deferTransactionUntilFrame,
-             Rect outFrame) {
-        mService.repositionChild(this, window, x, y, deferTransactionUntilFrame, outFrame);
+    public void repositionChild(IWindow window, int left, int top, int right, int bottom,
+             long deferTransactionUntilFrame, Rect outFrame) {
+        mService.repositionChild(this, window, left, top, right, bottom,
+                deferTransactionUntilFrame, outFrame);
     }
 
     public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 5864b25..46cd7cd 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -135,7 +135,7 @@
         stack.addTask(this, toTop);
     }
 
-    void positionTaskInStack(TaskStack stack, int position) {
+    void positionTaskInStack(TaskStack stack, int position, Rect bounds, Configuration config) {
         if (mStack != null && stack != mStack) {
             if (DEBUG_STACK) Slog.i(TAG, "positionTaskInStack: removing taskId=" + mTaskId
                     + " from stack=" + mStack);
@@ -143,6 +143,7 @@
             mStack.removeTask(this);
         }
         stack.positionTask(this, position, showForAllUsers());
+        setBounds(bounds, config);
     }
 
     boolean removeAppToken(AppWindowToken wtoken) {
@@ -252,8 +253,7 @@
         return false;
     }
 
-    /** Bounds of the task with other system factors taken into consideration. */
-    @Override
+    /** Original bounds of the task if applicable, otherwise fullscreen rect. */
     public void getBounds(Rect out) {
         if (useCurrentBounds()) {
             // No need to adjust the output bounds if fullscreen or the docked stack is visible
@@ -268,6 +268,70 @@
         mStack.getDisplayContent().getLogicalDisplayRect(out);
     }
 
+
+    /**
+     * Calculate the maximum visible area of this task. If the task has only one app,
+     * the result will be visible frame of that app. If the task has more than one apps,
+     * we search from top down if the next app got different visible area.
+     *
+     * This effort is to handle the case where some task (eg. GMail composer) might pop up
+     * a dialog that's different in size from the activity below, in which case we should
+     * be dimming the entire task area behind the dialog.
+     *
+     * @param out Rect containing the max visible bounds.
+     * @return true if the task has some visible app windows; false otherwise.
+     */
+    boolean getMaxVisibleBounds(Rect out) {
+        boolean foundTop = false;
+        for (int i = mAppTokens.size() - 1; i >= 0; i--) {
+            final AppWindowToken token = mAppTokens.get(i);
+            // skip hidden (or about to hide) apps
+            if (token.mIsExiting || token.clientHidden || token.hiddenRequested) {
+                continue;
+            }
+            final WindowState win = token.findMainWindow();
+            if (win == null) {
+                continue;
+            }
+            if (!foundTop) {
+                out.set(win.mVisibleFrame);
+                foundTop = true;
+                continue;
+            }
+            if (win.mVisibleFrame.left < out.left) {
+                out.left = win.mVisibleFrame.left;
+            }
+            if (win.mVisibleFrame.top < out.top) {
+                out.top = win.mVisibleFrame.top;
+            }
+            if (win.mVisibleFrame.right > out.right) {
+                out.right = win.mVisibleFrame.right;
+            }
+            if (win.mVisibleFrame.bottom > out.bottom) {
+                out.bottom = win.mVisibleFrame.bottom;
+            }
+        }
+        return foundTop;
+    }
+
+    /** Bounds of the task to be used for dimming, as well as touch related tests. */
+    @Override
+    public void getDimBounds(Rect out) {
+        if (useCurrentBounds()) {
+            if (inFreeformWorkspace() && getMaxVisibleBounds(out)) {
+                return;
+            }
+
+            out.set(mBounds);
+            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.
+        mStack.getDisplayContent().getLogicalDisplayRect(out);
+    }
+
     void setDragResizing(boolean dragResizing) {
         mDragResizing = dragResizing;
     }
@@ -328,6 +392,15 @@
         }
     }
 
+    /**
+     * Cancels any running thumbnail transitions associated with the task.
+     */
+    void cancelTaskThumbnailTransition() {
+        for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
+            mAppTokens.get(activityNdx).mAppAnimator.clearThumbnail();
+        }
+    }
+
     boolean showForAllUsers() {
         final int tokensCount = mAppTokens.size();
         return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
@@ -345,14 +418,20 @@
         return mStack != null && mStack.mStackId == DOCKED_STACK_ID;
     }
 
-    WindowState getTopAppMainWindow() {
-        final int tokensCount = mAppTokens.size();
-        return tokensCount > 0 ? mAppTokens.get(tokensCount - 1).findMainWindow() : null;
+    WindowState getTopVisibleAppMainWindow() {
+        final AppWindowToken token = getTopVisibleAppToken();
+        return token != null ? token.findMainWindow() : null;
     }
 
-    AppWindowToken getTopAppWindowToken() {
-        final int tokensCount = mAppTokens.size();
-        return tokensCount > 0 ? mAppTokens.get(tokensCount - 1) : null;
+    AppWindowToken getTopVisibleAppToken() {
+        for (int i = mAppTokens.size() - 1; i >= 0; i--) {
+            final AppWindowToken token = mAppTokens.get(i);
+            // skip hidden (or about to hide) apps
+            if (!token.mIsExiting && !token.clientHidden && !token.hiddenRequested) {
+                return token;
+            }
+        }
+        return null;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index aae3bd2..f5e4e3b 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -149,7 +149,7 @@
                         }
                         synchronized (mService.mWindowMap) {
                             mDragEnded = notifyMoveLocked(newX, newY);
-                            mTask.getBounds(mTmpRect);
+                            mTask.getDimBounds(mTmpRect);
                         }
                         if (!mTmpRect.equals(mWindowDragBounds)) {
                             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
@@ -332,28 +332,34 @@
                 + ", {" + startX + ", " + startY + "}");
         }
         mCtrlType = CTRL_NONE;
+        mTask = win.getTask();
+        mStartDragX = startX;
+        mStartDragY = startY;
+
+        // Use the dim bounds, not the original task bounds. The cursor
+        // movement should be calculated relative to the visible bounds.
+        // Also, use the dim bounds of the task which accounts for
+        // multiple app windows. Don't use any bounds from win itself as it
+        // may not be the same size as the task.
+        mTask.getDimBounds(mTmpRect);
+
         if (resize) {
-            final Rect visibleFrame = win.mVisibleFrame;
-            if (startX < visibleFrame.left) {
+            if (startX < mTmpRect.left) {
                 mCtrlType |= CTRL_LEFT;
             }
-            if (startX > visibleFrame.right) {
+            if (startX > mTmpRect.right) {
                 mCtrlType |= CTRL_RIGHT;
             }
-            if (startY < visibleFrame.top) {
+            if (startY < mTmpRect.top) {
                 mCtrlType |= CTRL_TOP;
             }
-            if (startY > visibleFrame.bottom) {
+            if (startY > mTmpRect.bottom) {
                 mCtrlType |= CTRL_BOTTOM;
             }
             mResizing = true;
         }
 
-        mTask = win.getTask();
-        mStartDragX = startX;
-        mStartDragY = startY;
-
-        mService.getTaskBounds(mTask.mTaskId, mWindowOriginalBounds);
+        mWindowOriginalBounds.set(mTmpRect);
     }
 
     private void endDragLocked() {
@@ -393,7 +399,7 @@
         }
 
         // This is a moving operation.
-        mTask.mStack.getBounds(mTmpRect);
+        mTask.mStack.getDimBounds(mTmpRect);
         mTmpRect.inset(mMinVisibleWidth, mMinVisibleHeight);
         if (!mTmpRect.contains((int) x, (int) y)) {
             // We end the moving operation if position is outside the stack bounds.
@@ -438,7 +444,7 @@
             return CTRL_NONE;
         }
 
-        mTask.mStack.getBounds(mTmpRect);
+        mTask.mStack.getDimBounds(mTmpRect);
         if (x - mSideMargin <= mTmpRect.left) {
             return CTRL_LEFT;
         }
@@ -450,7 +456,7 @@
     }
 
     private void showDimLayer() {
-        mTask.mStack.getBounds(mTmpRect);
+        mTask.mStack.getDimBounds(mTmpRect);
         if (mCurrentDimSide == CTRL_LEFT) {
             mTmpRect.right = mTmpRect.centerX();
         } else if (mCurrentDimSide == CTRL_RIGHT) {
@@ -473,7 +479,7 @@
     }
 
     @Override
-    public void getBounds(Rect out) {
+    public void getDimBounds(Rect out) {
         // This dim layer user doesn't need this.
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index f72384c..8085f13 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -16,16 +16,6 @@
 
 package com.android.server.wm;
 
-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.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
-import static com.android.server.wm.WindowManagerService.H.RESIZE_STACK;
-import static com.android.server.wm.WindowManagerService.TAG;
-
-import android.annotation.IntDef;
 import android.app.ActivityManager.StackId;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -39,10 +29,20 @@
 import com.android.server.EventLogTags;
 
 import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 
+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.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;
+import static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
+import static com.android.server.wm.WindowManagerService.H.RESIZE_STACK;
+import static com.android.server.wm.WindowManagerService.TAG;
+
 public class TaskStack implements DimLayer.DimLayerUser {
 
     // If the stack should be resized to fullscreen.
@@ -86,21 +86,6 @@
     /** Detach this stack from its display when animation completes. */
     boolean mDeferDetach;
 
-    static final int DOCKED_INVALID = -1;
-    static final int DOCKED_LEFT = 1;
-    static final int DOCKED_TOP = 2;
-    static final int DOCKED_RIGHT = 3;
-    static final int DOCKED_BOTTOM = 4;
-
-    @IntDef({
-            DOCKED_INVALID,
-            DOCKED_LEFT,
-            DOCKED_TOP,
-            DOCKED_RIGHT,
-            DOCKED_BOTTOM})
-    @Retention(RetentionPolicy.SOURCE)
-    @interface DockSide {}
-
     TaskStack(WindowManagerService service, int stackId) {
         mService = service;
         mStackId = stackId;
@@ -204,8 +189,6 @@
         return false;
     }
 
-    /** Bounds of the stack with other system factors taken into consideration. */
-    @Override
     public void getBounds(Rect out) {
         if (useCurrentBounds()) {
             // No need to adjust the output bounds if fullscreen or the docked stack is visible
@@ -220,6 +203,12 @@
         mDisplayContent.getLogicalDisplayRect(out);
     }
 
+    /** Bounds of the stack with other system factors taken into consideration. */
+    @Override
+    public void getDimBounds(Rect out) {
+        getBounds(out);
+    }
+
     void updateDisplayInfo(Rect bounds) {
         if (mDisplayContent != null) {
             for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -401,7 +390,7 @@
             final boolean dockedOnTopOrLeft = WindowManagerService.sDockedStackCreateMode
                     == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
             getStackDockedModeBounds(mTmpRect, bounds, mStackId, mTmpRect2,
-                    mDisplayContent.mDividerControllerLocked.getWidth(),
+                    mDisplayContent.mDividerControllerLocked.getContentWidth(),
                     dockedOnTopOrLeft);
         }
 
@@ -435,7 +424,6 @@
             return;
         }
 
-        @DockSide
         final int dockedSide = dockedStack.getDockSide();
         if (dockedSide == DOCKED_INVALID) {
             // Not sure how you got here...Only thing we can do is return current bounds.
@@ -446,9 +434,10 @@
 
         mDisplayContent.getLogicalDisplayRect(mTmpRect);
         dockedStack.getRawBounds(mTmpRect2);
-        final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
+        final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP
+                || dockedSide == DOCKED_LEFT;
         getStackDockedModeBounds(mTmpRect, outBounds, mStackId, mTmpRect2,
-                mDisplayContent.mDividerControllerLocked.getWidth(), dockedOnTopOrLeft);
+                mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
 
     }
 
@@ -519,7 +508,7 @@
             final boolean dockedOnTopOrLeft = WindowManagerService.sDockedStackCreateMode
                     == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
             getStackDockedModeBounds(bounds, bounds, FULLSCREEN_WORKSPACE_STACK_ID, dockedBounds,
-                    mDisplayContent.mDividerControllerLocked.getWidth(), dockedOnTopOrLeft);
+                    mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
         }
 
         final int count = mService.mStackIdToStack.size();
@@ -660,7 +649,6 @@
     /**
      * For docked workspace provides information which side of the screen was the dock anchored.
      */
-    @DockSide
     int getDockSide() {
         if (mStackId != DOCKED_STACK_ID) {
             return DOCKED_INVALID;
@@ -700,4 +688,26 @@
         }
         return false;
     }
+
+    /**
+     * Returns true if this stack has a window that is fully visible, doesn't perform an entry
+     * animation and is just positioned where it's supposed to be.
+     */
+    boolean hasWindowWithFinalVisibility() {
+        for (int i = mTasks.size() - 1; i >= 0; i--) {
+            Task task = mTasks.get(i);
+            for (int j = task.mAppTokens.size() - 1; j >= 0; j--) {
+                final AppWindowToken token = task.mAppTokens.get(j);
+                if (token.mAppAnimator.animating || token.mWillReplaceWindow) {
+                    continue;
+                }
+                WindowState win = token.findMainWindow();
+                if (win != null && !win.mWinAnimator.mEnterAnimationPending
+                        && !win.mWinAnimator.mEnteringAnimation) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index a33fb13..f5b83bb 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -90,11 +90,11 @@
             case MotionEvent.ACTION_HOVER_MOVE: {
                 final int x = (int) motionEvent.getX();
                 final int y = (int) motionEvent.getY();
-                final WindowState window = mDisplayContent.findWindowForControlPoint(x, y);
-                if (window == null) {
+                final Task task = mDisplayContent.findTaskForControlPoint(x, y);
+                if (task == null) {
                     break;
                 }
-                window.getVisibleBounds(mTmpRect, false);
+                task.getDimBounds(mTmpRect);
                 if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) {
                     int iconShape = STYLE_DEFAULT;
                     if (x < mTmpRect.left) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 4a9d8cb..8b984f0 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -149,11 +149,11 @@
     }
 
     void updateWallpaperVisibility() {
-        final boolean visible = isWallpaperVisible(mWallpaperTarget);
         final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
         if (displayContent == null) {
             return;
         }
+        final boolean visible = isWallpaperVisible(mWallpaperTarget);
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         final int dw = displayInfo.logicalWidth;
         final int dh = displayInfo.logicalHeight;
@@ -205,7 +205,7 @@
                 final WindowState wallpaper = token.windows.get(j);
                 final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
                 if (!winAnimator.mLastHidden || wasDeferred) {
-                    winAnimator.hide();
+                    winAnimator.hide("hideWallpapers");
                     dispatchWallpaperVisibility(wallpaper, false);
                     final DisplayContent displayContent = wallpaper.getDisplayContent();
                     if (displayContent != null) {
@@ -470,13 +470,13 @@
     }
 
     private void findWallpaperTarget(WindowList windows, FindWallpaperTargetResult result) {
-
         final WindowAnimator winAnimator = mService.mAnimator;
         result.reset();
         WindowState w = null;
         int windowDetachedI = -1;
         boolean resetTopWallpaper = false;
         boolean inFreeformSpace = false;
+        boolean replacing = false;
         for (int i = windows.size() - 1; i >= 0; i--) {
             w = windows.get(i);
             if ((w.mAttrs.type == TYPE_WALLPAPER)) {
@@ -504,12 +504,13 @@
                 inFreeformSpace = stack != null && stack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
             }
 
+            replacing = replacing || (w.mAppToken != null && w.mAppToken.mWillReplaceWindow);
+
             // If the app is executing an animation because the keyguard is going away,
             // keep the wallpaper during the animation so it doesn't flicker out.
             final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
                     || (w.mAppToken != null && w.mWinAnimator.mKeyguardGoingAwayAnimation);
-            if (hasWallpaper && w.isOnScreen()
-                    && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
+            if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
                 if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
                 result.setWallpaperTarget(w, i);
                 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
@@ -530,9 +531,12 @@
                     "Found animating detached wallpaper activity: #" + windowDetachedI + "=" + w);
             result.setWallpaperTarget(w, windowDetachedI);
         }
-        if (result.wallpaperTarget == null && inFreeformSpace) {
+        if (result.wallpaperTarget == null
+                && (inFreeformSpace || (replacing && mWallpaperTarget != null))) {
             // In freeform mode we set the wallpaper as its own target, so we don't need an
-            // additional window to make it visible.
+            // additional window to make it visible. When we are replacing a window and there was
+            // wallpaper before replacement, we want to keep the window until the new windows fully
+            // appear and can determine the visibility, to avoid flickering.
             result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index f4a4140..a96bd2c 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -18,29 +18,35 @@
 
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
-
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD;
-import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
-import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
 
 import android.content.Context;
-import android.os.RemoteException;
 import android.os.Trace;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
+import android.view.Choreographer;
 import android.view.Display;
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
-import android.view.Choreographer;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -61,7 +67,7 @@
     private final WindowSurfacePlacer mWindowPlacerLocked;
 
     /** Is any window animating? */
-    boolean mAnimating;
+    private boolean mAnimating;
 
     /** Is any app window animating? */
     boolean mAppWindowAnimating;
@@ -101,6 +107,10 @@
     static final int KEYGUARD_ANIMATING_OUT = 2;
     int mForceHiding = KEYGUARD_NOT_SHOWN;
 
+    // When set to true the animator will go over all windows after an animation frame is posted and
+    // check if some got replaced and can be removed.
+    private boolean mRemoveReplacedWindows = false;
+
     private String forceHidingToString() {
         switch (mForceHiding) {
             case KEYGUARD_NOT_SHOWN:    return "KEYGUARD_NOT_SHOWN";
@@ -158,13 +168,14 @@
                     appAnimator.wasAnimating = appAnimator.animating;
                     if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
                         appAnimator.animating = true;
-                        mAnimating = mAppWindowAnimating = true;
+                        setAnimating(true);
+                        mAppWindowAnimating = true;
                     } else if (appAnimator.wasAnimating) {
                         // stopped animating, do one more pass through the layout
                         setAppLayoutChanges(appAnimator,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
                                 "appToken " + appAnimator.mAppToken + " done", displayId);
-                        if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
+                        if (DEBUG_ANIM) Slog.v(TAG,
                                 "updateWindowsApps...: done animating " + appAnimator.mAppToken);
                     }
                 }
@@ -176,13 +187,14 @@
                 final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
                 appAnimator.wasAnimating = appAnimator.animating;
                 if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
-                    mAnimating = mAppWindowAnimating = true;
+                    setAnimating(true);
+                    mAppWindowAnimating = true;
                 } else if (appAnimator.wasAnimating) {
                     // stopped animating, do one more pass through the layout
                     setAppLayoutChanges(appAnimator,
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
                             "exiting appToken " + appAnimator.mAppToken + " done", displayId);
-                    if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
+                    if (DEBUG_ANIM) Slog.v(TAG,
                             "updateWindowsApps...: done animating exiting "
                                     + appAnimator.mAppToken);
                 }
@@ -267,13 +279,14 @@
             final int flags = win.mAttrs.flags;
             boolean canBeForceHidden = mPolicy.canBeForceHidden(win, win.mAttrs);
             boolean shouldBeForceHidden = shouldForceHide(win);
-            if (winAnimator.mSurfaceControl != null) {
+            if (winAnimator.mSurfaceController != null
+                    && winAnimator.mSurfaceController.hasSurface()) {
                 final boolean wasAnimating = winAnimator.mWasAnimating;
                 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
                 winAnimator.mWasAnimating = nowAnimating;
-                mAnimating |= nowAnimating;
+                orAnimating(nowAnimating);
 
-                if (WindowManagerService.DEBUG_WALLPAPER) {
+                if (DEBUG_WALLPAPER) {
                     Slog.v(TAG, win + ": wasAnimating=" + wasAnimating +
                             ", nowAnimating=" + nowAnimating);
                 }
@@ -283,7 +296,7 @@
                     mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                     setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
-                    if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                    if (DEBUG_LAYOUT_REPEATS) {
                         mWindowPlacerLocked.debugLayoutRepeats(
                                 "updateWindowsAndWallpaperLocked 2",
                                 getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
@@ -292,13 +305,13 @@
 
                 if (mPolicy.isForceHiding(win.mAttrs)) {
                     if (!wasAnimating && nowAnimating) {
-                        if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_ANIM ||
-                                WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                        if (DEBUG_KEYGUARD || DEBUG_ANIM ||
+                                DEBUG_VISIBILITY) Slog.v(TAG,
                                 "Animation started that could impact force hide: " + win);
                         mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
                         setPendingLayoutChanges(displayId,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
-                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                        if (DEBUG_LAYOUT_REPEATS) {
                             mWindowPlacerLocked.debugLayoutRepeats(
                                     "updateWindowsAndWallpaperLocked 3",
                                     getPendingLayoutChanges(displayId));
@@ -317,7 +330,7 @@
                             mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
                         }
                     }
-                    if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                    if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
                             "Force hide " + forceHidingToString()
                             + " hasSurface=" + win.mHasSurface
                             + " policyVis=" + win.mPolicyVisibility
@@ -332,7 +345,7 @@
                             // Was already hidden
                             continue;
                         }
-                        if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                        if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
                                 "Now policy hidden: " + win);
                     } else {
                         boolean applyExistingExitAnimation = mPostKeyguardExitAnimation != null
@@ -354,7 +367,7 @@
                             win.hideLw(false, false);
                             continue;
                         }
-                        if (DEBUG_KEYGUARD || WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                        if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
                                 "Now policy shown: " + win);
                         if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
                                 && win.mAttachedWindow == null) {
@@ -384,7 +397,7 @@
                             // We are showing on top of the current
                             // focus, so re-evaluate focus to make
                             // sure it is correct.
-                            if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG,
+                            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG,
                                     "updateWindowsLocked: setting mFocusMayChange true");
                             mService.mFocusMayChange = true;
                         }
@@ -393,7 +406,7 @@
                         mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                         setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
-                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                        if (DEBUG_LAYOUT_REPEATS) {
                             mWindowPlacerLocked.debugLayoutRepeats(
                                     "updateWindowsAndWallpaperLocked 4",
                                     getPendingLayoutChanges(Display.DEFAULT_DISPLAY));
@@ -418,7 +431,7 @@
                     if (winAnimator.performShowLocked()) {
                         setPendingLayoutChanges(displayId,
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
-                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                        if (DEBUG_LAYOUT_REPEATS) {
                             mWindowPlacerLocked.debugLayoutRepeats(
                                     "updateWindowsAndWallpaperLocked 5",
                                     getPendingLayoutChanges(displayId));
@@ -512,7 +525,7 @@
         for (int i = windows.size() - 1; i >= 0; i--) {
             final WindowState win = windows.get(i);
             WindowStateAnimator winAnimator = win.mWinAnimator;
-            if (winAnimator.mSurfaceControl == null) {
+            if (winAnimator.mSurfaceController == null) {
                 continue;
             }
 
@@ -535,7 +548,7 @@
                         }
                     }
                 }
-                mAnimating = true;
+                setAnimating(true);
             }
 
             // If this window's app token is running a detached wallpaper
@@ -560,7 +573,7 @@
         } // end forall windows
 
         if (mWindowDetachedWallpaper != detachedWallpaper) {
-            if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
+            if (DEBUG_WALLPAPER) Slog.v(TAG,
                     "Detached wallpaper changed from " + mWindowDetachedWallpaper
                     + " to " + detachedWallpaper);
             mWindowDetachedWallpaper = detachedWallpaper;
@@ -590,7 +603,7 @@
                         if (appAnimator.freezingScreen) {
                             appAnimator.showAllWindowsLocked();
                             mService.unsetAppFreezingScreenLocked(wtoken, false, true);
-                            if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
+                            if (DEBUG_ORIENTATION) Slog.i(TAG,
                                     "Setting mOrientationChangeComplete=true because wtoken "
                                     + wtoken + " numInteresting=" + wtoken.numInterestingWindows
                                     + " numDrawn=" + wtoken.numDrawnWindows);
@@ -606,7 +619,7 @@
 
                             // We can now show all of the drawn windows!
                             if (!mService.mOpeningApps.contains(wtoken)) {
-                                mAnimating |= appAnimator.showAllWindowsLocked();
+                                orAnimating(appAnimator.showAllWindowsLocked());
                             }
                         }
                     }
@@ -625,13 +638,13 @@
         mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
         mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
         boolean wasAnimating = mAnimating;
-        mAnimating = false;
+        setAnimating(false);
         mAppWindowAnimating = false;
-        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
+        if (DEBUG_WINDOW_TRACE) {
             Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
         }
 
-        if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
+        if (SHOW_TRANSACTIONS) Slog.i(
                 TAG, ">>> OPEN TRANSACTION animateLocked");
         SurfaceControl.openTransaction();
         SurfaceControl.setAnimationTransaction();
@@ -646,7 +659,7 @@
                         displayAnimator.mScreenRotationAnimation;
                 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
                     if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
-                        mAnimating = true;
+                        setAnimating(true);
                     } else {
                         mBulkUpdateParams |= SET_UPDATE_ROTATION;
                         screenRotationAnimation.kill();
@@ -686,7 +699,7 @@
                     screenRotationAnimation.updateSurfacesInTransaction();
                 }
 
-                mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers();
+                orAnimating(mService.getDisplayContentLocked(displayId).animateDimLayers());
 
                 //TODO (multidisplay): Magnification is supported only for the default display.
                 if (mService.mAccessibilityController != null
@@ -706,7 +719,7 @@
             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
         } finally {
             SurfaceControl.closeTransaction();
-            if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
+            if (SHOW_TRANSACTIONS) Slog.i(
                     TAG, "<<< CLOSE TRANSACTION animateLocked");
         }
 
@@ -743,16 +756,40 @@
             }
         }
 
+        if (mRemoveReplacedWindows) {
+            removeReplacedWindowsLocked();
+        }
+
         mService.destroyPreservedSurfaceLocked();
 
-        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
+        if (DEBUG_WINDOW_TRACE) {
             Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
-                + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
-                + " mPendingLayoutChanges(DEFAULT_DISPLAY)="
-                + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY)));
+                    + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
+                    + " mPendingLayoutChanges(DEFAULT_DISPLAY)="
+                    + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY)));
         }
     }
 
+    private void removeReplacedWindowsLocked() {
+        if (SHOW_TRANSACTIONS) Slog.i(
+                TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
+        SurfaceControl.openTransaction();
+        try {
+            for (int i = mService.mDisplayContents.size() - 1; i >= 0; i--) {
+                DisplayContent display = mService.mDisplayContents.get(i);
+                final WindowList windows = mService.getWindowListLocked(display.getDisplayId());
+                for (int j = windows.size() - 1; j >= 0; j--) {
+                    windows.get(j).maybeRemoveReplacedWindow();
+                }
+            }
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_TRANSACTIONS) Slog.i(
+                    TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
+        }
+        mRemoveReplacedWindows = false;
+    }
+
     private static String bulkUpdateParamsToString(int bulkUpdateParams) {
         StringBuilder builder = new StringBuilder(128);
         if ((bulkUpdateParams & WindowSurfacePlacer.SET_UPDATE_ROTATION) != 0) {
@@ -843,7 +880,7 @@
         for (int i = windows.size() - 1; i >= 0; i--) {
             if (displayId == windows.get(i).getDisplayId()) {
                 setPendingLayoutChanges(displayId, changes);
-                if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                if (DEBUG_LAYOUT_REPEATS) {
                     mWindowPlacerLocked.debugLayoutRepeats(reason,
                             getPendingLayoutChanges(displayId));
                 }
@@ -874,7 +911,27 @@
         return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation;
     }
 
+    void requestRemovalOfReplacedWindows(WindowState win) {
+        final AppWindowToken token = win.mAppToken;
+        if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == win) {
+            token.mHasReplacedWindow = true;
+        }
+        mRemoveReplacedWindows = true;
+    }
+
     private class DisplayContentsAnimator {
         ScreenRotationAnimation mScreenRotationAnimation = null;
     }
+
+    boolean isAnimating() {
+        return mAnimating;
+    }
+
+    void setAnimating(boolean animating) {
+        mAnimating = animating;
+    }
+
+    void orAnimating(boolean animating) {
+        mAnimating |= animating;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b3f9ddb..c6b6c77 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -19,8 +19,10 @@
 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.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.StatusBarManager.DISABLE_MASK;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
+import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -31,8 +33,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -46,16 +46,15 @@
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
+import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 
-import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
-
 import android.Manifest;
 import android.animation.ValueAnimator;
 import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
-import android.app.StatusBarManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -116,6 +115,7 @@
 import android.view.DropPermissionHolder;
 import android.view.Gravity;
 import android.view.IApplicationToken;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IInputFilter;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
@@ -223,6 +223,7 @@
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
+    static final boolean SHOW_VERBOSE_TRANSACTIONS = false && SHOW_TRANSACTIONS;
     static final boolean HIDE_STACK_CRAWLS = true;
     static final int LAYOUT_REPEAT_THRESHOLD = 4;
 
@@ -700,7 +701,7 @@
                             if (DEBUG_DRAG) Slog.d(TAG, "Button no longer pressed; dropping at "
                                     + newX + "," + newY);
                             synchronized (mWindowMap) {
-                                endDrag = completeDrop(newX, newY);
+                                endDrag = completeDropLw(newX, newY);
                             }
                         } else {
                             synchronized (mWindowMap) {
@@ -714,7 +715,7 @@
                         if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
                                 + newX + "," + newY);
                         synchronized (mWindowMap) {
-                            endDrag = completeDrop(newX, newY);
+                            endDrag = completeDropLw(newX, newY);
                         }
                     } break;
 
@@ -744,11 +745,15 @@
         }
     }
 
-    private boolean completeDrop(float x, float y) {
+    private boolean completeDropLw(float x, float y) {
         WindowState dropTargetWin = mDragState.getDropTargetWinLw(x, y);
 
+        mDragState.mCurrentX = x;
+        mDragState.mCurrentY = y;
+
         DropPermissionHolder dropPermissionHolder = null;
-        if ((mDragState.mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
+        if (dropTargetWin != null &&
+                (mDragState.mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
                 (mDragState.mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
             dropPermissionHolder = new DropPermissionHolder(
                     mDragState.mData,
@@ -903,7 +908,7 @@
                 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
         mScreenFrozenLock.setReferenceCounted(false);
 
-        mAppTransition = new AppTransition(context, mH);
+        mAppTransition = new AppTransition(context, mH, mWindowMap, mWindowPlacerLocked);
         mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
 
         mActivityManager = ActivityManagerNative.getDefault();
@@ -1235,7 +1240,16 @@
         final int myLayer = win.mBaseLayer;
         int i;
         for (i = windows.size() - 1; i >= 0; i--) {
-            if (windows.get(i).mBaseLayer <= myLayer) {
+            final WindowState otherWin = windows.get(i);
+            if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= myLayer) {
+                // Wallpaper wanders through the window list, for example to position itself
+                // directly behind keyguard. Because of this it will break the ordering based on
+                // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
+                // we don't want the new window to appear above them. An example of this is adding
+                // of the docked stack divider. Consider a scenario with the following ordering (top
+                // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
+                // to land below the assist preview, so the dock divider must ignore the wallpaper,
+                // with which it shares the base layer.
                 break;
             }
         }
@@ -1352,7 +1366,7 @@
             if (DEBUG_INPUT_METHOD) {
                 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
                 if (!w.isVisibleOrAdding()) {
-                    Slog.i(TAG, "  mSurface=" + w.mWinAnimator.mSurfaceControl
+                    Slog.i(TAG, "  mSurfaceController=" + w.mWinAnimator.mSurfaceController
                             + " relayoutCalled=" + w.mRelayoutCalled
                             + " viewVis=" + w.mViewVisibility
                             + " policyVis=" + w.mPolicyVisibility
@@ -1518,7 +1532,7 @@
             // TODO(multidisplay): IMEs are only supported on the default display.
             getDefaultWindowListLocked().add(pos, win);
             mWindowsChanged = true;
-            moveInputMethodDialogsLocked(pos+1);
+            moveInputMethodDialogsLocked(pos + 1);
             return;
         }
         win.mTargetAppToken = null;
@@ -1897,11 +1911,6 @@
                             + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
-            } else if (type == TYPE_DOCK_DIVIDER) {
-                if (displayContent.mDividerControllerLocked.hasDivider()) {
-                    Slog.w(TAG, "Attempted to add docked stack divider twice. Aborting.");
-                    return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                }
             } else if (token.appWindowToken != null) {
                 Slog.w(TAG, "Non-null appWindowToken for system window of type=" + type);
                 // It is not valid to use an app token with other system types; we will
@@ -2000,6 +2009,10 @@
                 }
             }
 
+            if (type == TYPE_DOCK_DIVIDER) {
+                getDefaultDisplayContentLocked().getDockedDividerController().setWindow(win);
+            }
+
             final WindowStateAnimator winAnimator = win.mWinAnimator;
             winAnimator.mEnterAnimationPending = true;
             winAnimator.mEnteringAnimation = true;
@@ -2062,7 +2075,7 @@
     }
 
     private void prepareWindowReplacementTransition(AppWindowToken atoken) {
-        if (atoken == null || !atoken.mWillReplaceWindow || !atoken.mAnimateReplacingWindow) {
+        if (atoken == null || !atoken.mWillReplaceWindow) {
             return;
         }
         atoken.allDrawn = false;
@@ -2078,7 +2091,9 @@
             // happen, let's just simply add a window.
             return;
         }
-        Rect frame = replacedWindow.mFrame;
+        // We use the visible frame, because we want the animation to morph the window from what
+        // was visible to the user to the final destination of the new window.
+        Rect frame = replacedWindow.mVisibleFrame;
         // We treat this as if this activity was opening, so we can trigger the app transition
         // animation and piggy-back on existing transition animation infrastructure.
         mOpeningApps.add(atoken);
@@ -2153,7 +2168,7 @@
         if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
                 TAG, "Remove " + win + " client="
                 + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
-                + ", surface=" + win.mWinAnimator.mSurfaceControl + " Callers="
+                + ", surfaceController=" + win.mWinAnimator.mSurfaceController + " Callers="
                 + Debug.getCallers(4));
 
         final long origId = Binder.clearCallingIdentity();
@@ -2161,7 +2176,7 @@
         win.disposeInputChannel();
 
         if (DEBUG_APP_TRANSITIONS) Slog.v(
-                TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl
+                TAG, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
                 + " mExiting=" + win.mExiting
                 + " isAnimating=" + win.mWinAnimator.isAnimating()
                 + " app-animation="
@@ -2225,7 +2240,8 @@
                     mAccessibilityController.onWindowTransitionLocked(win, transit);
                 }
             }
-            final boolean isAnimating = win.mWinAnimator.isAnimating();
+            final boolean isAnimating = win.mWinAnimator.isAnimating()
+                    && !win.mWinAnimator.isDummyAnimation();
             // The starting window is the last window in this app token and it isn't animating.
             // Allow it to be removed now as there is no additional window or animation that will
             // trigger its removal.
@@ -2407,6 +2423,9 @@
         try {
             synchronized (mWindowMap) {
                 WindowState w = windowForClientLocked(session, client, false);
+                if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "transparentRegionHint=" + region, null);
+
                 if ((w != null) && w.mHasSurface) {
                     w.mWinAnimator.setTransparentRegionHintLocked(region);
                 }
@@ -2484,7 +2503,8 @@
     }
 
     void repositionChild(Session session, IWindow client,
-            int x, int y, long deferTransactionUntilFrame, Rect outFrame) {
+            int top, int left, int right, int bottom,
+            long deferTransactionUntilFrame, Rect outFrame) {
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "repositionChild");
         long origId = Binder.clearCallingIdentity();
 
@@ -2500,8 +2520,10 @@
                             + "attached to a parent win=" + win);
                 }
 
-                win.mFrame.left = x;
-                win.mFrame.top = y;
+                win.mFrame.left = left;
+                win.mFrame.top = top;
+                win.mFrame.right = right;
+                win.mFrame.bottom = bottom;
 
                 win.mWinAnimator.computeShownFrameLocked();
 
@@ -2512,8 +2534,8 @@
                 SurfaceControl.openTransaction();
 
                 if (deferTransactionUntilFrame > 0) {
-                    win.mWinAnimator.mSurfaceControl.deferTransactionUntil(
-                            win.mAttachedWindow.mWinAnimator.mSurfaceControl.getHandle(),
+                    win.mWinAnimator.mSurfaceController.deferTransactionUntil(
+                            win.mAttachedWindow.mWinAnimator.mSurfaceController.getHandle(),
                             deferTransactionUntilFrame);
                 }
                 win.mWinAnimator.setSurfaceBoundariesLocked(false);
@@ -2537,11 +2559,8 @@
             Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
             Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig,
             Surface outSurface) {
-        boolean toBeDisplayed = false;
-        boolean inTouchMode;
+        int result = 0;
         boolean configChanged;
-        boolean surfaceChanged = false;
-        boolean dragResizing = false;
         boolean hasStatusBarPermission =
                 mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                         == PackageManager.PERMISSION_GRANTED;
@@ -2558,35 +2577,34 @@
                 win.setRequestedSize(requestedWidth, requestedHeight);
             }
 
-            if (attrs != null) {
-                mPolicy.adjustWindowParamsLw(attrs);
-            }
-
-            // if they don't have the permission, mask out the status bar bits
-            int systemUiVisibility = 0;
-            if (attrs != null) {
-                systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
-                if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
-                    if (!hasStatusBarPermission) {
-                        systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
-                    }
-                }
-            }
-
-            if (attrs != null && seq == win.mSeq) {
-                win.mSystemUiVisibility = systemUiVisibility;
-            }
-
-            winAnimator.mSurfaceDestroyDeferred =
-                    (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
-
             int attrChanges = 0;
             int flagChanges = 0;
             if (attrs != null) {
+                mPolicy.adjustWindowParamsLw(attrs);
+                // if they don't have the permission, mask out the status bar bits
+                if (seq == win.mSeq) {
+                    int systemUiVisibility = attrs.systemUiVisibility
+                            | attrs.subtreeSystemUiVisibility;
+                    if ((systemUiVisibility & DISABLE_MASK) != 0) {
+                        if (!hasStatusBarPermission) {
+                            systemUiVisibility &= ~DISABLE_MASK;
+                        }
+                    }
+                    win.mSystemUiVisibility = systemUiVisibility;
+                }
                 if (win.mAttrs.type != attrs.type) {
                     throw new IllegalArgumentException(
                             "Window type can not be changed after the window is added.");
                 }
+
+                // Odd choice but less odd than embedding in copyFrom()
+                if ((attrs.flags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY) != 0) {
+                    attrs.x = win.mAttrs.x;
+                    attrs.y = win.mAttrs.y;
+                    attrs.width = win.mAttrs.width;
+                    attrs.height = win.mAttrs.height;
+                }
+
                 flagChanges = win.mAttrs.flags ^= attrs.flags;
                 attrChanges = win.mAttrs.copyFrom(attrs);
                 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
@@ -2597,30 +2615,15 @@
 
             if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
                     + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
-
+            winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
             win.mEnforceSizeCompat =
                     (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
-
             if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
                 winAnimator.mAlpha = attrs.alpha;
             }
-
-            final boolean scaledWindow =
-                ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
-
-            if (scaledWindow) {
-                // requested{Width|Height} Surface's physical size
-                // attrs.{width|height} Size on screen
-                win.mHScale = (attrs.width  != requestedWidth)  ?
-                        (attrs.width  / (float)requestedWidth) : 1.0f;
-                win.mVScale = (attrs.height != requestedHeight) ?
-                        (attrs.height / (float)requestedHeight) : 1.0f;
-            } else {
-                win.mHScale = win.mVScale = 1;
-            }
+            win.setWindowScale(requestedWidth, requestedHeight);
 
             boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
-
             final boolean isDefaultDisplay = win.isDefaultDisplay();
             boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
                     || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
@@ -2629,8 +2632,8 @@
             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
                     && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
             wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
-            if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceControl != null) {
-                winAnimator.mSurfaceControl.setSecure(isSecureLocked(win));
+            if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
+                winAnimator.mSurfaceController.setSecure(isSecureLocked(win));
             }
 
             win.mRelayoutCalled = true;
@@ -2644,78 +2647,10 @@
             }
             if (viewVisibility == View.VISIBLE &&
                     (win.mAppToken == null || !win.mAppToken.clientHidden)) {
-                toBeDisplayed = !win.isVisibleLw();
-                if (win.mExiting) {
-                    winAnimator.cancelExitAnimationForNextAnimationLocked();
-                    win.mExiting = false;
-                }
-                if (win.mDestroying) {
-                    win.mDestroying = false;
-                    mDestroySurface.remove(win);
-                }
-                if (oldVisibility == View.GONE) {
-                    winAnimator.mEnterAnimationPending = true;
-                }
-                winAnimator.mEnteringAnimation = true;
-                if (toBeDisplayed) {
-                    if ((win.mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
-                            == SOFT_INPUT_ADJUST_RESIZE) {
-                        win.mLayoutNeeded = true;
-                    }
-                    if (win.isDrawnLw() && okToDisplay()) {
-                        winAnimator.applyEnterAnimationLocked();
-                    }
-                    if ((win.mAttrs.flags
-                            & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
-                        if (DEBUG_VISIBILITY) Slog.v(TAG,
-                                "Relayout window turning screen on: " + win);
-                        win.mTurnOnScreen = true;
-                    }
-                    if (win.isConfigChanged()) {
-                        if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
-                                + " visible with new config: " + mCurConfiguration);
-                        outConfig.setTo(mCurConfiguration);
-                    }
-                }
-                if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
-                    // If the format can be changed in place yaay!
-                    // If not, fall back to a surface re-build
-                    if (!winAnimator.tryChangeFormatInPlaceLocked()) {
-                        winAnimator.destroySurfaceLocked();
-                        toBeDisplayed = true;
-                        surfaceChanged = true;
-                    }
-                }
-
-                // If we're starting a drag-resize, we'll be changing the surface size as well as
-                // notifying the client to render to with an offset from the surface's top-left.
-                if (win.isDragResizeChanged()) {
-                    win.setDragResizing();
-                    if (win.mHasSurface) {
-                        winAnimator.preserveSurfaceLocked();
-                        toBeDisplayed = true;
-                    }
-                }
-                dragResizing = win.isDragResizing();
-                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.
-                    toBeDisplayed = true;
-                }
+                result = relayoutVisibleWindow(outConfig, result, win, winAnimator, attrChanges,
+                        oldVisibility);
                 try {
-                    if (!win.mHasSurface) {
-                        surfaceChanged = true;
-                    }
-                    SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
-                    if (surfaceControl != null) {
-                        outSurface.copyFrom(surfaceControl);
-                        if (SHOW_TRANSACTIONS) Slog.i(TAG,
-                                "  OUT SURFACE " + outSurface + ": copied");
-                    } else {
-                        // For some reason there isn't a surface.  Clear the
-                        // caller's object so they see the same state.
-                        outSurface.release();
-                    }
+                    result = createSurfaceControl(outSurface, result, win, winAnimator);
                 } catch (Exception e) {
                     mInputMonitor.updateInputWindowsLw(true /*force*/);
 
@@ -2725,31 +2660,19 @@
                     Binder.restoreCallingIdentity(origId);
                     return 0;
                 }
-                if (toBeDisplayed) {
+                if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
                     focusMayChange = isDefaultDisplay;
                 }
-                if (win.mAttrs.type == TYPE_INPUT_METHOD
-                        && mInputMethodWindow == null) {
+                if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) {
                     mInputMethodWindow = win;
                     imMayMove = true;
                 }
-                if (win.mAttrs.type == TYPE_BASE_APPLICATION
-                        && win.mAppToken != null
-                        && win.mAppToken.startingWindow != null) {
-                    // Special handling of starting window over the base
-                    // window of the app: propagate lock screen flags to it,
-                    // to provide the correct semantics while starting.
-                    final int mask =
-                        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
-                        | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
-                    WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
-                    sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
-                }
+                win.adjustStartingWindowFlags();
             } else {
                 winAnimator.mEnterAnimationPending = false;
                 winAnimator.mEnteringAnimation = false;
-                if (winAnimator.mSurfaceControl != null) {
+                if (winAnimator.mSurfaceController != null &&
+                        winAnimator.mSurfaceController.hasSurface()) {
                     if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
                             + ": mExiting=" + win.mExiting);
                     // If we are using a saved surface to do enter animation, just let the
@@ -2759,41 +2682,14 @@
                     // don't want to destroy the saved surface.
                     // If we are not currently running the exit animation, we
                     // need to see about starting one.
-                    if (!win.mExiting && !win.isAnimatingWithSavedSurface()) {
-                        surfaceChanged = true;
-                        // Try starting an animation; if there isn't one, we
-                        // can destroy the surface right away.
-                        int transit = WindowManagerPolicy.TRANSIT_EXIT;
-                        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
-                            transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
-                        }
-                        if (win.isWinVisibleLw() &&
-                                winAnimator.applyAnimationLocked(transit, false)) {
-                            focusMayChange = isDefaultDisplay;
-                            win.mExiting = true;
-                        } else if (win.mWinAnimator.isAnimating()) {
-                            // Currently in a hide animation... turn this into
-                            // an exit.
-                            win.mExiting = true;
-                        } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
-                            // If the wallpaper is currently behind this
-                            // window, we need to change both of them inside
-                            // of a transaction to avoid artifacts.
-                            win.mExiting = true;
-                            win.mWinAnimator.mAnimating = true;
-                        } else {
-                            if (mInputMethodWindow == win) {
-                                mInputMethodWindow = null;
-                            }
-                            if (!win.shouldSaveSurface()) {
-                                winAnimator.destroySurfaceLocked();
-                            }
-                        }
-                        //TODO (multidisplay): Magnification is supported only for the default
-                        if (mAccessibilityController != null
-                                && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
-                            mAccessibilityController.onWindowTransitionLocked(win, transit);
-                        }
+                    final boolean notExitingOrAnimating =
+                            !win.mExiting && !win.isAnimatingWithSavedSurface();
+                    result |= notExitingOrAnimating
+                            ? RELAYOUT_RES_SURFACE_CHANGED : 0;
+                    if (notExitingOrAnimating) {
+                        focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay,
+                                focusMayChange);
+
                     }
                 }
 
@@ -2812,6 +2708,7 @@
 
             // updateFocusedWindowLocked() already assigned layers so we only need to
             // reassign them at this point if the IM window state gets shuffled
+            boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
             if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
                 // Little hack here -- we -should- be able to rely on the
                 // function to return true if the IME has moved and needs
@@ -2838,6 +2735,10 @@
             if (win.mAppToken != null) {
                 win.mAppToken.updateReportedVisibilityLocked();
             }
+            if (winAnimator.mReportSurfaceResized) {
+                winAnimator.mReportSurfaceResized = false;
+                result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED;
+            }
             outFrame.set(win.mCompatFrame);
             outOverscanInsets.set(win.mOverscanInsets);
             outContentInsets.set(win.mContentInsets);
@@ -2855,7 +2756,7 @@
             if (localLOGV || DEBUG_FOCUS) Slog.v(
                 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
 
-            inTouchMode = mInTouchMode;
+            result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
 
             mInputMonitor.updateInputWindowsLw(true /*force*/);
 
@@ -2867,13 +2768,108 @@
         if (configChanged) {
             sendNewConfiguration();
         }
-
         Binder.restoreCallingIdentity(origId);
+        return result;
+    }
 
-        return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
-                | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
-                | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
-                | (dragResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 0);
+    private boolean tryStartingAnimation(WindowState win, WindowStateAnimator winAnimator,
+            boolean isDefaultDisplay, boolean focusMayChange) {
+        // Try starting an animation; if there isn't one, we
+        // can destroy the surface right away.
+        int transit = WindowManagerPolicy.TRANSIT_EXIT;
+        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
+            transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
+        }
+        if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
+            focusMayChange = isDefaultDisplay;
+            win.mExiting = true;
+        } else if (win.mWinAnimator.isAnimating()) {
+            // Currently in a hide animation... turn this into
+            // an exit.
+            win.mExiting = true;
+        } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
+            // If the wallpaper is currently behind this
+            // window, we need to change both of them inside
+            // of a transaction to avoid artifacts.
+            win.mExiting = true;
+            win.mWinAnimator.mAnimating = true;
+        } else {
+            if (mInputMethodWindow == win) {
+                mInputMethodWindow = null;
+            }
+            if (!win.shouldSaveSurface()) {
+                winAnimator.destroySurfaceLocked();
+            }
+        }
+        //TODO (multidisplay): Magnification is supported only for the default
+        if (mAccessibilityController != null
+                && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
+            mAccessibilityController.onWindowTransitionLocked(win, transit);
+        }
+        return focusMayChange;
+    }
+
+    private int createSurfaceControl(Surface outSurface, int result, WindowState win,
+            WindowStateAnimator winAnimator) {
+        if (!win.mHasSurface) {
+            result |= RELAYOUT_RES_SURFACE_CHANGED;
+        }
+        WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked();
+        if (surfaceController != null) {
+            surfaceController.getSurface(outSurface);
+            if (SHOW_TRANSACTIONS) Slog.i(TAG, "  OUT SURFACE " + outSurface + ": copied");
+        } else {
+            // For some reason there isn't a surface.  Clear the
+            // caller's object so they see the same state.
+            outSurface.release();
+        }
+        return result;
+    }
+
+    private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win,
+            WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) {
+        result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0;
+        if (win.mExiting) {
+            winAnimator.cancelExitAnimationForNextAnimationLocked();
+            win.mExiting = false;
+        }
+        if (win.mDestroying) {
+            win.mDestroying = false;
+            mDestroySurface.remove(win);
+        }
+        if (oldVisibility == View.GONE) {
+            winAnimator.mEnterAnimationPending = true;
+        }
+        winAnimator.mEnteringAnimation = true;
+        if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
+            win.prepareWindowToDisplayDuringRelayout(outConfig);
+        }
+        if ((attrChanges& LayoutParams.FORMAT_CHANGED) != 0) {
+            // If the format can be changed in place yaay!
+            // If not, fall back to a surface re-build
+            if (!winAnimator.tryChangeFormatInPlaceLocked()) {
+                winAnimator.destroySurfaceLocked();
+                result |= RELAYOUT_RES_SURFACE_CHANGED
+                        | WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
+            }
+        }
+
+        // If we're starting a drag-resize, we'll be changing the surface size as well as
+        // notifying the client to render to with an offset from the surface's top-left.
+        if (win.isDragResizeChanged()) {
+            win.setDragResizing();
+            if (win.mHasSurface) {
+                winAnimator.preserveSurfaceLocked();
+                result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
+            }
+        }
+        result |= win.isDragResizing() ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING : 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.
+            result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
+        }
+        return result;
     }
 
     public void performDeferredDestroyWindow(Session session, IWindow client) {
@@ -3537,13 +3533,6 @@
                 mLastFinishedFreezeSource = "new-config";
             }
             mWindowPlacerLocked.performSurfacePlacement();
-            if (orientationChanged) {
-                for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
-                    DisplayContent content = mDisplayContents.valueAt(i);
-                    Message.obtain(mH, H.UPDATE_DOCKED_STACK_DIVIDER, H.DOCK_DIVIDER_FORCE_UPDATE,
-                            H.UNUSED, content).sendToTarget();
-                }
-            }
         }
     }
 
@@ -3690,8 +3679,8 @@
             int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
             boolean scaleUp) {
         synchronized(mWindowMap) {
-            mAppTransition.overridePendingAppTransitionAspectScaledThumb(srcThumb, startX,
-                    startY, targetWidth, targetHeight, startedCallback, scaleUp);
+            mAppTransition.overridePendingAppTransitionAspectScaledThumb(srcThumb, startX, startY,
+                    targetWidth, targetHeight, startedCallback, scaleUp);
         }
     }
 
@@ -3731,6 +3720,16 @@
     }
 
     @Override
+    public void overridePendingAppTransitionMultiThumbFuture(
+            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
+            boolean scaleUp) {
+        synchronized(mWindowMap) {
+            mAppTransition.overridePendingAppTransitionMultiThumbFuture(specsFuture, callback,
+                    scaleUp);
+        }
+    }
+
+    @Override
     public void endProlongedAnimations() {
         synchronized (mWindowMap) {
             for (final WindowState win : mWindowMap.values()) {
@@ -4715,6 +4714,16 @@
         }
     }
 
+    @Override
+    public void cancelTaskThumbnailTransition(int taskId) {
+        synchronized (mWindowMap) {
+            Task task = mTaskIdToTask.get(taskId);
+            if (task != null) {
+                task.cancelTaskThumbnailTransition();
+            }
+        }
+    }
+
     public void addTask(int taskId, int stackId, boolean toTop) {
         synchronized (mWindowMap) {
             if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId
@@ -4800,7 +4809,8 @@
         }
     }
 
-    public void positionTaskInStack(int taskId, int stackId, int position) {
+    public void positionTaskInStack(int taskId, int stackId, int position, Rect bounds,
+            Configuration config) {
         synchronized (mWindowMap) {
             if (DEBUG_STACK) Slog.i(TAG, "positionTaskInStack: positioning taskId=" + taskId
                     + " in stackId=" + stackId + " at " + position);
@@ -4816,7 +4826,7 @@
                         "positionTaskInStack: could not find stackId=" + stackId);
                 return;
             }
-            task.positionTaskInStack(stack, position);
+            task.positionTaskInStack(stack, position, bounds, config);
             final DisplayContent displayContent = stack.getDisplayContent();
             displayContent.layoutNeeded = true;
             mWindowPlacerLocked.performSurfacePlacement();
@@ -5633,7 +5643,7 @@
                 }
             }
 
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+            if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG,
                     ">>> OPEN TRANSACTION showStrictModeViolation");
             SurfaceControl.openTransaction();
             try {
@@ -5645,7 +5655,7 @@
                 mStrictModeFlash.setVisibility(on);
             } finally {
                 SurfaceControl.closeTransaction();
-                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG,
                         "<<< CLOSE TRANSACTION showStrictModeViolation");
             }
         }
@@ -5825,11 +5835,12 @@
                     // Include this window.
 
                     final WindowStateAnimator winAnim = ws.mWinAnimator;
-                    if (maxLayer < winAnim.mSurfaceLayer) {
-                        maxLayer = winAnim.mSurfaceLayer;
+                    int layer = winAnim.mSurfaceController.getLayer();
+                    if (maxLayer < layer) {
+                        maxLayer = layer;
                     }
-                    if (minLayer > winAnim.mSurfaceLayer) {
-                        minLayer = winAnim.mSurfaceLayer;
+                    if (minLayer > layer) {
+                        minLayer = layer;
                     }
 
                     // Don't include wallpaper in bounds calculation
@@ -5841,7 +5852,7 @@
                         int right = wf.right - cr.right;
                         int bottom = wf.bottom - cr.bottom;
                         frame.union(left, top, right, bottom);
-                        ws.getVisibleBounds(stackBounds, !BOUNDS_FOR_TOUCH);
+                        ws.getVisibleBounds(stackBounds);
                         if (!frame.intersect(stackBounds)) {
                             // Set frame empty if there's no intersection.
                             frame.setEmpty();
@@ -5849,7 +5860,7 @@
                     }
 
                     if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
-                            ws.isDisplayedLw() && winAnim.mSurfaceShown) {
+                            ws.isDisplayedLw() && winAnim.getShown()) {
                         screenshotReady = true;
                     }
 
@@ -5939,7 +5950,7 @@
                         WindowState win = windows.get(i);
                         Slog.i(TAG, win + ": " + win.mLayer
                                 + " animLayer=" + win.mWinAnimator.mAnimLayer
-                                + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
+                                + " surfaceLayer=" + win.mWinAnimator.mSurfaceController.getLayer());
                     }
                 }
 
@@ -5977,7 +5988,8 @@
             if (allBlack) {
                 Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
                         Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
-                        (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
+                        (appWin != null ?
+                                appWin.mWinAnimator.mSurfaceController.getLayer() : "null") +
                         " minLayer=" + minLayer + " maxLayer=" + maxLayer);
             }
         }
@@ -6894,27 +6906,25 @@
         final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
         final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        synchronized(displayContent.mDisplaySizeLock) {
-            displayInfo.rotation = mRotation;
-            displayInfo.logicalWidth = dw;
-            displayInfo.logicalHeight = dh;
-            displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
-            displayInfo.appWidth = appWidth;
-            displayInfo.appHeight = appHeight;
-            displayInfo.getLogicalMetrics(mRealDisplayMetrics,
-                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
-            displayInfo.getAppMetrics(mDisplayMetrics);
-            if (displayContent.mDisplayScalingDisabled) {
-                displayInfo.flags |= Display.FLAG_SCALING_DISABLED;
-            } else {
-                displayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
-            }
-
-            mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
-                    displayContent.getDisplayId(), displayInfo);
-
-            displayContent.mBaseDisplayRect.set(0, 0, dw, dh);
+        displayInfo.rotation = mRotation;
+        displayInfo.logicalWidth = dw;
+        displayInfo.logicalHeight = dh;
+        displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
+        displayInfo.appWidth = appWidth;
+        displayInfo.appHeight = appHeight;
+        displayInfo.getLogicalMetrics(mRealDisplayMetrics,
+                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+        displayInfo.getAppMetrics(mDisplayMetrics);
+        if (displayContent.mDisplayScalingDisabled) {
+            displayInfo.flags |= Display.FLAG_SCALING_DISABLED;
+        } else {
+            displayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
         }
+
+        mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
+                displayContent.getDisplayId(), displayInfo);
+
+        displayContent.mBaseDisplayRect.set(0, 0, dw, dh);
         if (false) {
             Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
         }
@@ -7059,15 +7069,16 @@
     }
 
     private void startResizingTask(DisplayContent displayContent, int startX, int startY) {
-        WindowState win = null;
+        Task task = null;
         synchronized (mWindowMap) {
-            win = displayContent.findWindowForControlPoint(startX, startY);
-            if (win == null || !startPositioningLocked(win, true /*resize*/, startX, startY)) {
+            task = displayContent.findTaskForControlPoint(startX, startY);
+            if (task == null || !startPositioningLocked(
+                    task.getTopVisibleAppMainWindow(), true /*resize*/, startX, startY)) {
                 return;
             }
         }
         try {
-            mActivityManager.setFocusedTask(win.getTask().mTaskId);
+            mActivityManager.setFocusedTask(task.mTaskId);
         } catch(RemoteException e) {}
     }
 
@@ -7135,6 +7146,7 @@
                     + " asbinder=" + window.asBinder());
         }
 
+        final int callerPid = Binder.getCallingPid();
         final int callerUid = Binder.getCallingUid();
         final long origId = Binder.clearCallingIdentity();
         IBinder token = null;
@@ -7160,6 +7172,7 @@
                         final IBinder winBinder = window.asBinder();
                         token = new Binder();
                         mDragState = new DragState(this, token, surface, flags, winBinder);
+                        mDragState.mPid = callerPid;
                         mDragState.mUid = callerUid;
                         token = mDragState.mToken = new Binder();
 
@@ -7385,16 +7398,6 @@
         public static final int RESIZE_TASK = 44;
 
         /**
-         * Used to indicate in the message that the dock divider needs to be updated only if it's
-         * necessary.
-         */
-        static final int DOCK_DIVIDER_NO_FORCE_UPDATE = 0;
-        /**
-         * Used to indicate in the message that the dock divider should be force-removed before
-         * updating, so new configuration can be applied.
-         */
-        static final int DOCK_DIVIDER_FORCE_UPDATE = 1;
-        /**
          * Used to denote that an integer field in a message will not be used.
          */
         public static final int UNUSED = 0;
@@ -7680,7 +7683,7 @@
                     synchronized (mWindowMap) {
                         // Since we're holding both mWindowMap and mAnimator we don't need to
                         // hold mAnimator.mLayoutToAnim.
-                        if (mAnimator.mAnimating || mAnimationScheduled) {
+                        if (mAnimator.isAnimating() || mAnimationScheduled) {
                             // If we are animating, don't do the gc now but
                             // delay a bit so we don't interrupt the animation.
                             sendEmptyMessageDelayed(H.FORCE_GC, 2000);
@@ -7937,12 +7940,10 @@
                         }
                     }
                 }
-                break;
                 case UPDATE_DOCKED_STACK_DIVIDER: {
-                    DisplayContent content = (DisplayContent) msg.obj;
-                    final boolean forceUpdate = msg.arg1 == DOCK_DIVIDER_FORCE_UPDATE;
                     synchronized (mWindowMap) {
-                        content.mDividerControllerLocked.update(mCurConfiguration, forceUpdate);
+                        getDefaultDisplayContentLocked().getDockedDividerController()
+                                .reevaluateVisibility();
                     }
                 }
                 break;
@@ -8055,10 +8056,8 @@
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
-                synchronized(displayContent.mDisplaySizeLock) {
-                    size.x = displayContent.mInitialDisplayWidth;
-                    size.y = displayContent.mInitialDisplayHeight;
-                }
+                size.x = displayContent.mInitialDisplayWidth;
+                size.y = displayContent.mInitialDisplayHeight;
             }
         }
     }
@@ -8068,10 +8067,8 @@
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
-                synchronized(displayContent.mDisplaySizeLock) {
-                    size.x = displayContent.mBaseDisplayWidth;
-                    size.y = displayContent.mBaseDisplayHeight;
-                }
+                size.x = displayContent.mBaseDisplayWidth;
+                size.y = displayContent.mBaseDisplayHeight;
             }
         }
     }
@@ -8140,13 +8137,9 @@
         }
     }
 
-    private void setForcedDisplayScalingModeLocked(DisplayContent displayContent,
-            int mode) {
+    private void setForcedDisplayScalingModeLocked(DisplayContent displayContent, int mode) {
         Slog.i(TAG, "Using display scaling mode: " + (mode == 0 ? "auto" : "off"));
-
-        synchronized(displayContent.mDisplaySizeLock) {
-            displayContent.mDisplayScalingDisabled = (mode != 0);
-        }
+        displayContent.mDisplayScalingDisabled = (mode != 0);
         reconfigureDisplayLocked(displayContent);
     }
 
@@ -8164,13 +8157,11 @@
                 try {
                     width = Integer.parseInt(sizeStr.substring(0, pos));
                     height = Integer.parseInt(sizeStr.substring(pos+1));
-                    synchronized(displayContent.mDisplaySizeLock) {
-                        if (displayContent.mBaseDisplayWidth != width
-                                || displayContent.mBaseDisplayHeight != height) {
-                            Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
-                            displayContent.mBaseDisplayWidth = width;
-                            displayContent.mBaseDisplayHeight = height;
-                        }
+                    if (displayContent.mBaseDisplayWidth != width
+                            || displayContent.mBaseDisplayHeight != height) {
+                        Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
+                        displayContent.mBaseDisplayWidth = width;
+                        displayContent.mBaseDisplayHeight = height;
                     }
                 } catch (NumberFormatException ex) {
                 }
@@ -8187,11 +8178,9 @@
             int density;
             try {
                 density = Integer.parseInt(densityStr);
-                synchronized(displayContent.mDisplaySizeLock) {
-                    if (displayContent.mBaseDisplayDensity != density) {
-                        Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
-                        displayContent.mBaseDisplayDensity = density;
-                    }
+                if (displayContent.mBaseDisplayDensity != density) {
+                    Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
+                    displayContent.mBaseDisplayDensity = density;
                 }
             } catch (NumberFormatException ex) {
             }
@@ -8201,21 +8190,16 @@
         int mode = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.DISPLAY_SCALING_FORCE, 0);
         if (mode != 0) {
-            synchronized(displayContent.mDisplaySizeLock) {
-                Slog.i(TAG, "FORCED DISPLAY SCALING DISABLED");
-                displayContent.mDisplayScalingDisabled = true;
-            }
+            Slog.i(TAG, "FORCED DISPLAY SCALING DISABLED");
+            displayContent.mDisplayScalingDisabled = true;
         }
     }
 
     // displayContent must not be null
     private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
         Slog.i(TAG, "Using new display size: " + width + "x" + height);
-
-        synchronized(displayContent.mDisplaySizeLock) {
-            displayContent.mBaseDisplayWidth = width;
-            displayContent.mBaseDisplayHeight = height;
-        }
+        displayContent.mBaseDisplayWidth = width;
+        displayContent.mBaseDisplayHeight = height;
         reconfigureDisplayLocked(displayContent);
     }
 
@@ -8251,9 +8235,7 @@
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
-                synchronized(displayContent.mDisplaySizeLock) {
-                    return displayContent.mInitialDisplayDensity;
-                }
+                return displayContent.mInitialDisplayDensity;
             }
         }
         return -1;
@@ -8264,9 +8246,7 @@
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
-                synchronized(displayContent.mDisplaySizeLock) {
-                    return displayContent.mBaseDisplayDensity;
-                }
+                return displayContent.mBaseDisplayDensity;
             }
         }
         return -1;
@@ -8301,10 +8281,7 @@
     // displayContent must not be null
     private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
         Slog.i(TAG, "Using new display density: " + density);
-
-        synchronized(displayContent.mDisplaySizeLock) {
-            displayContent.mBaseDisplayDensity = density;
-        }
+        displayContent.mBaseDisplayDensity = density;
         reconfigureDisplayLocked(displayContent);
     }
 
@@ -8395,12 +8372,10 @@
     private void setOverscanLocked(DisplayContent displayContent,
             int left, int top, int right, int bottom) {
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        synchronized (displayContent.mDisplaySizeLock) {
-            displayInfo.overscanLeft = left;
-            displayInfo.overscanTop = top;
-            displayInfo.overscanRight = right;
-            displayInfo.overscanBottom = bottom;
-        }
+        displayInfo.overscanLeft = left;
+        displayInfo.overscanTop = top;
+        displayInfo.overscanRight = right;
+        displayInfo.overscanBottom = bottom;
 
         mDisplaySettings.setOverscanLocked(displayInfo.uniqueId, displayInfo.name, left, top,
                 right, bottom);
@@ -8560,8 +8535,7 @@
             final WindowStateAnimator winAnimator = w.mWinAnimator;
             boolean layerChanged = false;
             int oldLayer = w.mLayer;
-            if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
-                    || (i > 0 && w.mIsWallpaper)) {
+            if (w.mBaseLayer == curBaseLayer || w.mIsImWindow || (i > 0 && w.mIsWallpaper)) {
                 curLayer += WINDOW_LAYER_MULTIPLIER;
                 w.mLayer = curLayer;
             } else {
@@ -8580,8 +8554,7 @@
             } else if (wtoken != null) {
                 winAnimator.mAnimLayer =
                         w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
-                if (wtoken.mWillReplaceWindow && wtoken.mAnimateReplacingWindow &&
-                        wtoken.mReplacingWindow != w) {
+                if (wtoken.mWillReplaceWindow && wtoken.mReplacingWindow != w) {
                     // We know that we will be animating a relaunching window in the near future,
                     // which will receive a z-order increase. We want the replaced window to
                     // immediately receive the same treatment, e.g. to be above the dock divider.
@@ -8741,9 +8714,11 @@
                 // we need to go through the process of getting informed by the
                 // application when it has finished drawing.
                 if (w.mOrientationChanging || dragResizingChanged) {
-                    if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
-                            "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
-                            + w + ", surface " + winAnimator.mSurfaceControl);
+                    if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
+                        Slog.v(TAG, "Orientation or resize start waiting for draw"
+                                + ", mDrawState=DRAW_PENDING in " + w
+                                + ", surfaceController " + winAnimator.mSurfaceController);
+                    }
                     winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
                     if (w.mAppToken != null) {
                         w.mAppToken.allDrawn = false;
@@ -8752,15 +8727,14 @@
                 }
                 if (!mResizingWindows.contains(w)) {
                     if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
-                            "Resizing window " + w + " to " + winAnimator.mSurfaceW
-                            + "x" + winAnimator.mSurfaceH);
+                            "Resizing window " + w);
                     mResizingWindows.add(w);
                 }
             } else if (w.mOrientationChanging) {
                 if (w.isDrawnLw()) {
                     if (DEBUG_ORIENTATION) Slog.v(TAG,
                             "Orientation not waiting for draw in "
-                            + w + ", surface " + winAnimator.mSurfaceControl);
+                            + w + ", surfaceController " + winAnimator.mSurfaceController);
                     w.mOrientationChanging = false;
                     w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                             - mDisplayFreezeTime);
@@ -8857,7 +8831,7 @@
 
     boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
                                            boolean secure) {
-        final SurfaceControl surface = winAnimator.mSurfaceControl;
+        final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
         boolean leakedSurface = false;
         boolean killedApps = false;
 
@@ -8878,30 +8852,25 @@
                 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
                     final WindowState ws = windows.get(winNdx);
                     WindowStateAnimator wsa = ws.mWinAnimator;
-                    if (wsa.mSurfaceControl != null) {
+                    if (wsa.mSurfaceController != null) {
                         if (!mSessions.contains(wsa.mSession)) {
                             Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
-                                    + ws + " surface=" + wsa.mSurfaceControl
+                                    + ws + " surface=" + wsa.mSurfaceController
                                     + " token=" + ws.mToken
                                     + " pid=" + ws.mSession.mPid
                                     + " uid=" + ws.mSession.mUid);
-                            if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
-                            wsa.mSurfaceControl.destroy();
-                            wsa.mSurfaceShown = false;
-                            wsa.mSurfaceControl = null;
-                            ws.mHasSurface = false;
+                            wsa.destroySurface();
+                            ws.setHasSurface(false);
                             mForceRemoves.add(ws);
                             leakedSurface = true;
                         } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
                             Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
-                                    + ws + " surface=" + wsa.mSurfaceControl
+                                    + ws + " surface=" + wsa.mSurfaceController
                                     + " token=" + ws.mAppToken
                                     + " saved=" + ws.mAppToken.mHasSavedSurface);
                             if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
-                            wsa.mSurfaceControl.destroy();
-                            wsa.mSurfaceShown = false;
-                            wsa.mSurfaceControl = null;
-                            ws.mHasSurface = false;
+                            wsa.destroySurface();
+                            ws.setHasSurface(false);
                             ws.mAppToken.mHasSavedSurface = false;
                             leakedSurface = true;
                         }
@@ -8921,7 +8890,7 @@
                             continue;
                         }
                         WindowStateAnimator wsa = ws.mWinAnimator;
-                        if (wsa.mSurfaceControl != null) {
+                        if (wsa.mSurfaceController != null) {
                             pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
                         }
                     }
@@ -8944,13 +8913,11 @@
                 // We managed to reclaim some memory, so get rid of the trouble
                 // surface and ask the app to request another one.
                 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
-                if (surface != null) {
+                if (surfaceController != null) {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
                             "RECOVER DESTROY", null);
-                    surface.destroy();
-                    winAnimator.mSurfaceShown = false;
-                    winAnimator.mSurfaceControl = null;
-                    winAnimator.mWin.mHasSurface = false;
+                    surfaceController.destroyInTransaction();
+                    winAnimator.mWin.setHasSurface(false);
                     scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
                 }
 
@@ -9426,11 +9393,11 @@
             if (windowState == null) {
                 return false;
             }
-            SurfaceControl surfaceControl = windowState.mWinAnimator.mSurfaceControl;
-            if (surfaceControl == null) {
+            WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
+            if (surfaceController == null) {
                 return false;
             }
-            return surfaceControl.clearContentFrameStats();
+            return surfaceController.clearWindowContentFrameStats();
         }
     }
 
@@ -9445,15 +9412,15 @@
             if (windowState == null) {
                 return null;
             }
-            SurfaceControl surfaceControl = windowState.mWinAnimator.mSurfaceControl;
-            if (surfaceControl == null) {
+            WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
+            if (surfaceController == null) {
                 return null;
             }
             if (mTempWindowRenderStats == null) {
                 mTempWindowRenderStats = new WindowContentFrameStats();
             }
             WindowContentFrameStats stats = mTempWindowRenderStats;
-            if (!surfaceControl.getContentFrameStats(stats)) {
+            if (!surfaceController.getWindowContentFrameStats(stats)) {
                 return null;
             }
             return stats;
@@ -9740,7 +9707,7 @@
                             mDisplayContents.valueAt(displayNdx).getWindowList();
                     for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
                         final WindowState w = windowList.get(winNdx);
-                        if (w.mWinAnimator.mSurfaceShown
+                        if (w.mWinAnimator.getShown()
                                 && (!appsOnly || (appsOnly && w.mAppToken != null))) {
                             windows.add(w);
                         }
@@ -9900,7 +9867,7 @@
                 return;
             } else if ("surfaces".equals(cmd)) {
                 synchronized(mWindowMap) {
-                    WindowStateAnimator.SurfaceTrace.dumpAllSurfaces(pw, null);
+                    WindowSurfaceController.SurfaceTrace.dumpAllSurfaces(pw, null);
                 }
                 return;
             } else if ("displays".equals(cmd) || "d".equals(cmd)) {
@@ -9958,7 +9925,7 @@
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            WindowStateAnimator.SurfaceTrace.dumpAllSurfaces(pw, dumpAll ?
+            WindowSurfaceController.SurfaceTrace.dumpAllSurfaces(pw, dumpAll ?
                     "-------------------------------------------------------------------------------"
                     : null);
             pw.println();
@@ -9994,14 +9961,11 @@
         DisplayInfo displayInfo = displayContent.getDisplayInfo();
         final Rect rect = new Rect();
         mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
-        synchronized (displayContent.mDisplaySizeLock) {
-            displayInfo.overscanLeft = rect.left;
-            displayInfo.overscanTop = rect.top;
-            displayInfo.overscanRight = rect.right;
-            displayInfo.overscanBottom = rect.bottom;
-            mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
-                    displayId, displayInfo);
-        }
+        displayInfo.overscanLeft = rect.left;
+        displayInfo.overscanTop = rect.top;
+        displayInfo.overscanRight = rect.right;
+        displayInfo.overscanBottom = rect.bottom;
+        mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId, displayInfo);
         configureDisplayPolicyLocked(displayContent);
 
         // TODO: Create an input channel for each display with touch capability.
@@ -10127,9 +10091,8 @@
      * Hint to a token that its activity will relaunch, which will trigger removal and addition of
      * a window.
      * @param token Application token for which the activity will be relaunched.
-     * @param animate Whether to animate the addition of the new window.
      */
-    public void setReplacingWindow(IBinder token, boolean animate) {
+    public void setReplacingWindow(IBinder token) {
         synchronized (mWindowMap) {
             AppWindowToken appWindowToken = findAppWindowToken(token);
             if (appWindowToken == null) {
@@ -10139,10 +10102,37 @@
             if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Marking app token " + appWindowToken
                     + " as replacing window.");
             appWindowToken.mWillReplaceWindow = true;
-            appWindowToken.mAnimateReplacingWindow = animate;
+            appWindowToken.mHasReplacedWindow = false;
+
+            // Set-up dummy animation so we can start treating windows associated with this token
+            // like they are in transition before the new app window is ready for us to run the
+            // real transition animation.
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "setReplacingWindow() Setting dummy animation on: " + appWindowToken);
+            appWindowToken.mAppAnimator.setDummyAnimation();
         }
     }
 
+    @Override
+    public int getDockedStackSide() {
+        synchronized (mWindowMap) {
+            TaskStack dockedStack = getDefaultDisplayContentLocked().getDockedStackLocked();
+            return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
+        }
+    }
+
+    @Override
+    public void setDockedStackResizing(boolean resizing) {
+        synchronized (mWindowMap) {
+            getDefaultDisplayContentLocked().getDockedDividerController().setResizing(resizing);
+            requestTraversal();
+        }
+    }
+
+    boolean isDockedStackResizingLocked() {
+        return getDefaultDisplayContentLocked().getDockedDividerController().isResizing();
+    }
+
     static int dipToPixel(int dip, DisplayMetrics displayMetrics) {
         return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3b0fc4f..c6f7f4c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -16,59 +16,35 @@
 
 package com.android.server.wm;
 
-import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
-import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-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_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
-import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
-import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
-import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import com.android.server.input.InputWindowHandle;
 
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
-import android.graphics.Point;
-import android.os.PowerManager;
-import android.os.RemoteCallbackList;
-import android.os.SystemClock;
-import android.os.Trace;
-import android.os.WorkSource;
-import android.util.DisplayMetrics;
-import android.util.TimeUtils;
-import android.view.Display;
-import android.view.IWindowFocusObserver;
-import android.view.IWindowId;
-
-import com.android.server.input.InputWindowHandle;
-
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.IBinder;
+import android.os.PowerManager;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.Trace;
 import android.os.UserHandle;
+import android.os.WorkSource;
+import android.util.DisplayMetrics;
 import android.util.Slog;
+import android.util.TimeUtils;
+import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Gravity;
 import android.view.IApplicationToken;
 import android.view.IWindow;
+import android.view.IWindowFocusObserver;
+import android.view.IWindowId;
 import android.view.InputChannel;
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
@@ -80,6 +56,40 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
+import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
+import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
+import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+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_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
+import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
+import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+
 class WindowList extends ArrayList<WindowState> {
 }
 
@@ -99,7 +109,8 @@
     // to capture touch events in that area.
     static final int RESIZE_HANDLE_WIDTH_IN_DP = 30;
 
-    static final boolean BOUNDS_FOR_TOUCH = true;
+    static final int DRAG_RESIZE_MODE_FREEFORM = 0;
+    static final int DRAG_RESIZE_MODE_DOCKED_DIVIDER = 1;
 
     final WindowManagerService mService;
     final WindowManagerPolicy mPolicy;
@@ -138,6 +149,7 @@
     boolean mAttachedHidden;    // is our parent window hidden?
     boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
     boolean mDragResizing;
+    int mResizeMode;
 
     RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
 
@@ -606,7 +618,7 @@
         final int ph = mContainingFrame.height();
 
         int w,h;
-        if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
+        if ((mAttrs.flags & FLAG_SCALED) != 0) {
             if (mAttrs.width < 0) {
                 w = pw;
             } else if (mEnforceSizeCompat) {
@@ -718,8 +730,18 @@
             mVisibleFrame.set(mContentFrame);
             mStableFrame.set(mContentFrame);
         } else if (mAttrs.type == TYPE_DOCK_DIVIDER) {
-            mDisplayContent.mDividerControllerLocked.positionDockedStackedDivider(mFrame);
-            mContentFrame.set(mFrame);
+            if (isVisibleLw()) {
+                // We don't adjust the dock divider frame for reasons other than performance. The
+                // real reason is that if it gets adjusted before it is shown for the first time,
+                // it would get size (0, 0). This causes a problem when we finally show the dock
+                // divider and try to draw to it. We do set the surface size at that moment to
+                // the correct size, but it's too late for the Surface Flinger to make it
+                // available for view rendering and as a result the renderer receives size 1, 1.
+                // This way we just keep the divider at the original size and Surface Flinger
+                // will return the correct value to the renderer.
+                mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame);
+                mContentFrame.set(mFrame);
+            }
         } else {
             mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
                     Math.max(mContentFrame.top, mFrame.top),
@@ -951,17 +973,15 @@
     /**
      * Retrieves the visible bounds of the window.
      * @param bounds The rect which gets the bounds.
-     * @param forTouch Pass in BOUNDS_FOR_TOUCH to get touch related bounds, otherwise visible
-     *        bounds will be returned.
      */
-    void getVisibleBounds(Rect bounds, boolean forTouch) {
+    void getVisibleBounds(Rect bounds) {
         boolean intersectWithStackBounds = mAppToken != null && mAppToken.mCropWindowsToStack;
         bounds.setEmpty();
         mTmpRect.setEmpty();
         if (intersectWithStackBounds) {
             final TaskStack stack = getStack();
             if (stack != null) {
-                stack.getBounds(mTmpRect);
+                stack.getDimBounds(mTmpRect);
             } else {
                 intersectWithStackBounds = false;
             }
@@ -979,12 +999,6 @@
             }
             return;
         }
-        if (forTouch && inFreeformWorkspace()) {
-            final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
-            final int delta = WindowManagerService.dipToPixel(
-                    RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
-            bounds.inset(-delta, -delta);
-        }
     }
 
     public long getInputDispatchingTimeoutNanos() {
@@ -1284,6 +1298,10 @@
         mConfigHasChanged = false;
     }
 
+    void setHasSurface(boolean hasSurface) {
+        mHasSurface = hasSurface;
+    }
+
     private final class DeadWindowEventReceiver extends InputEventReceiver {
         DeadWindowEventReceiver(InputChannel inputChannel) {
             super(inputChannel, mService.mH.getLooper());
@@ -1340,6 +1358,14 @@
     }
 
     void applyDimLayerIfNeeded() {
+        // When the app is terminated (eg. from Recents), the task might have already been
+        // removed with the window pending removal. Don't apply dim in such cases, as there
+        // will be no more updateDimLayer() calls, which leaves the dimlayer invalid.
+        final AppWindowToken token = mAppToken;
+        if (token != null && token.removed) {
+            return;
+        }
+
         if (!mExiting && mAppDied) {
             // If app died visible, apply a dim over the window to indicate that it's inactive
             mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator);
@@ -1359,14 +1385,15 @@
 
     void maybeRemoveReplacedWindow() {
         AppWindowToken token = mAppToken;
-        if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == this) {
+        if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == this
+                && token.mHasReplacedWindow) {
             if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replacing window: " + this);
             token.mWillReplaceWindow = false;
-            token.mAnimateReplacingWindow = false;
             token.mReplacingRemoveRequested = false;
             token.mReplacingWindow = null;
+            token.mHasReplacedWindow = false;
             for (int i = token.allAppWindows.size() - 1; i >= 0; i--) {
-                WindowState win = token.allAppWindows.get(i);
+                final WindowState win = token.allAppWindows.get(i);
                 if (win.mExiting) {
                     mService.removeWindowInnerLocked(win);
                 }
@@ -1384,30 +1411,32 @@
         return mAppToken != null && mAppToken.mTask != null && mAppToken.mTask.inDockedWorkspace();
     }
 
-    int getTouchableRegion(Region region, int flags, InputMonitor inputMonitor) {
-        final boolean modal = (flags & (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) == 0;
+    int getTouchableRegion(Region region, int flags) {
+        final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
         if (modal && mAppToken != null) {
             // Limit the outer touch to the activity stack region.
-            flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-            if (!inFreeformWorkspace()) {
-                // If this is a modal window we need to dismiss it if it's not full screen and the
-                // touch happens outside of the frame that displays the content. This means we
-                // need to intercept touches outside of that window. The dim layer user
-                // associated with the window (task or stack) will give us the good bounds, as
-                // they would be used to display the dim layer.
-                final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
-                if (dimLayerUser != null) {
-                    dimLayerUser.getBounds(mTmpRect);
-                } else {
-                    getVisibleBounds(mTmpRect, BOUNDS_FOR_TOUCH);
-                }
+            flags |= FLAG_NOT_TOUCH_MODAL;
+            // If this is a modal window we need to dismiss it if it's not full screen and the
+            // touch happens outside of the frame that displays the content. This means we
+            // need to intercept touches outside of that window. The dim layer user
+            // associated with the window (task or stack) will give us the good bounds, as
+            // they would be used to display the dim layer.
+            final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
+            if (dimLayerUser != null) {
+                dimLayerUser.getDimBounds(mTmpRect);
             } else {
+                getVisibleBounds(mTmpRect);
+            }
+            if (inFreeformWorkspace()) {
                 // For freeform windows we the touch region to include the whole surface for the
                 // shadows.
-                getVisibleBounds(mTmpRect, BOUNDS_FOR_TOUCH);
+                final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
+                final int delta = WindowManagerService.dipToPixel(
+                        RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
+                mTmpRect.inset(-delta, -delta);
             }
             region.set(mTmpRect);
+            cropRegionToStackBoundsIfNeeded(region);
         } else {
             // Not modal or full screen modal
             getTouchableRegion(region);
@@ -1422,9 +1451,7 @@
                         mWinAnimator + ": " + mPolicyVisibilityAfterAnim);
             }
             mPolicyVisibility = mPolicyVisibilityAfterAnim;
-            if (mDisplayContent != null) {
-                mDisplayContent.layoutNeeded = true;
-            }
+            setDisplayLayoutNeeded();
             if (!mPolicyVisibility) {
                 if (mService.mCurrentFocus == this) {
                     if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
@@ -1447,6 +1474,54 @@
         }
     }
 
+    void prepareWindowToDisplayDuringRelayout(Configuration outConfig) {
+        if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
+                == SOFT_INPUT_ADJUST_RESIZE) {
+            mLayoutNeeded = true;
+        }
+        if (isDrawnLw() && mService.okToDisplay()) {
+            mWinAnimator.applyEnterAnimationLocked();
+        }
+        if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
+            if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
+            mTurnOnScreen = true;
+        }
+        if (isConfigChanged()) {
+            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: "
+                    + mService.mCurConfiguration);
+            outConfig.setTo(mService.mCurConfiguration);
+        }
+    }
+
+    void adjustStartingWindowFlags() {
+        if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null
+                && mAppToken.startingWindow != null) {
+            // Special handling of starting window over the base
+            // window of the app: propagate lock screen flags to it,
+            // to provide the correct semantics while starting.
+            final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD
+                    | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+            WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs;
+            sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask);
+        }
+    }
+
+    void setWindowScale(int requestedWidth, int requestedHeight) {
+        final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0;
+
+        if (scaledWindow) {
+            // requested{Width|Height} Surface's physical size
+            // attrs.{width|height} Size on screen
+            // TODO: We don't check if attrs != null here. Is it implicitly checked?
+            mHScale = (mAttrs.width  != requestedWidth)  ?
+                    (mAttrs.width  / (float)requestedWidth) : 1.0f;
+            mVScale = (mAttrs.height != requestedHeight) ?
+                    (mAttrs.height / (float)requestedHeight) : 1.0f;
+        } else {
+            mHScale = mVScale = 1;
+        }
+    }
+
     private class DeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
@@ -1633,7 +1708,7 @@
 
         Task task = getTask();
         if (task == null || task.inHomeStack()
-                || task.getTopAppWindowToken() != mAppToken) {
+                || task.getTopVisibleAppToken() != mAppToken) {
             // Don't save surfaces for home stack apps. These usually resume and draw
             // first frame very fast. Saving surfaces are mostly a waste of memory.
             // Don't save if the window is not the topmost window.
@@ -1697,26 +1772,41 @@
                 frame.right - inset.right, frame.bottom - inset.bottom);
     }
 
-    public void getTouchableRegion(Region outRegion) {
+    void getTouchableRegion(Region outRegion) {
         final Rect frame = mFrame;
         switch (mTouchableInsets) {
             default:
-            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
+            case TOUCHABLE_INSETS_FRAME:
                 outRegion.set(frame);
                 break;
-            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
+            case TOUCHABLE_INSETS_CONTENT:
                 applyInsets(outRegion, frame, mGivenContentInsets);
                 break;
-            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
+            case TOUCHABLE_INSETS_VISIBLE:
                 applyInsets(outRegion, frame, mGivenVisibleInsets);
                 break;
-            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
+            case TOUCHABLE_INSETS_REGION: {
                 final Region givenTouchableRegion = mGivenTouchableRegion;
                 outRegion.set(givenTouchableRegion);
                 outRegion.translate(frame.left, frame.top);
                 break;
             }
         }
+        cropRegionToStackBoundsIfNeeded(outRegion);
+    }
+
+    void cropRegionToStackBoundsIfNeeded(Region region) {
+        if (mAppToken == null || !mAppToken.mCropWindowsToStack) {
+            return;
+        }
+
+        final TaskStack stack = getStack();
+        if (stack == null) {
+            return;
+        }
+
+        stack.getDimBounds(mTmpRect);
+        region.op(mTmpRect, Region.Op.INTERSECT);
     }
 
     WindowList getWindowList() {
@@ -1761,7 +1851,7 @@
                     (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
             if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) {
                 Slog.i(TAG, "Sending new config to window " + this + ": "
-                        + mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH + " / config="
+                        + " / config="
                         + mService.mCurConfiguration + " overrideConfig=" + overrideConfig);
             }
             setConfiguration(mService.mCurConfiguration, overrideConfig);
@@ -1783,15 +1873,15 @@
                     @Override
                     public void run() {
                         try {
-                            mClient.resized(frame, overscanInsets, contentInsets,
-                                    visibleInsets, stableInsets, outsets, reportDraw, newConfig);
+                            dispatchResized(frame, overscanInsets, contentInsets, visibleInsets,
+                                    stableInsets, outsets, reportDraw, newConfig);
                         } catch (RemoteException e) {
                             // Not a remote call, RemoteException won't be raised.
                         }
                     }
                 });
             } else {
-                mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
+                dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
                         outsets, reportDraw, newConfig);
             }
 
@@ -1820,6 +1910,23 @@
         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);
+        // 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.
+        boolean resizing = isDragResizing() || isDragResizeChanged();
+        final Rect backDropFrame = (inFreeformWorkspace() || !resizing) ? frame : mTmpRect;
+        mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
+                outsets, reportDraw, newConfig, backDropFrame);
+    }
+
     public void registerFocusObserver(IWindowFocusObserver observer) {
         synchronized(mService.mWindowMap) {
             if (mFocusCallbacks == null) {
@@ -1852,6 +1959,10 @@
         return mDragResizing != computeDragResizing();
     }
 
+    int getResizeMode() {
+        return mResizeMode;
+    }
+
     private boolean computeDragResizing() {
         final Task task = getTask();
         if (task == null) {
@@ -1866,6 +1977,9 @@
 
     void setDragResizing() {
         mDragResizing = computeDragResizing();
+        mResizeMode = mDragResizing && mDisplayContent.mDividerControllerLocked.isResizing()
+                ? DRAG_RESIZE_MODE_DOCKED_DIVIDER
+                : DRAG_RESIZE_MODE_FREEFORM;
     }
 
     boolean isDragResizing() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index ec97ba8..6faf3a7 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -16,7 +16,9 @@
 
 package com.android.server.wm;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
@@ -24,11 +26,12 @@
 import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerService.localLOGV;
 import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
+import static com.android.server.wm.WindowManagerService.localLOGV;
+import static com.android.server.wm.WindowState.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
 
@@ -36,21 +39,18 @@
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
-import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Debug;
 import android.os.RemoteException;
 import android.util.Slog;
-import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.MagnificationSpec;
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
-import android.view.SurfaceSession;
 import android.view.WindowManager;
-import android.view.WindowManagerPolicy;
 import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 import android.view.animation.AnimationSet;
 import android.view.animation.AnimationUtils;
@@ -59,7 +59,6 @@
 import com.android.server.wm.WindowManagerService.H;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Keep track of animations and surface operations for a single WindowState.
@@ -94,14 +93,18 @@
     long mAnimationStartTime;
     long mLastAnimationTime;
 
-    SurfaceControl mSurfaceControl;
-    SurfaceControl mPendingDestroySurface;
-
     /**
      * Set when we have changed the size of the surface, to know that
      * we must tell them application to resize (and thus redraw itself).
      */
     boolean mSurfaceResized;
+    /**
+     * Whether we should inform the client on next relayoutWindow that
+     * the surface has been resized since last time.
+     */
+    boolean mReportSurfaceResized;
+    WindowSurfaceController mSurfaceController;
+    private WindowSurfaceController mPendingDestroySurface;
 
     /**
      * Set if the client has asked that the destroy of its surface be delayed
@@ -109,7 +112,7 @@
      */
     boolean mSurfaceDestroyDeferred;
 
-    boolean mDestroyPreservedSurfaceUponRedraw;
+    private boolean mDestroyPreservedSurfaceUponRedraw;
     float mShownAlpha = 0;
     float mAlpha = 0;
     float mLastAlpha = 0;
@@ -120,29 +123,18 @@
     Rect mLastClipRect = new Rect();
     Rect mTmpStackBounds = new Rect();
 
-    // Used to save animation distances between the time they are calculated and when they are
-    // used.
-    int mAnimDw;
-    int mAnimDh;
+    // Used to save animation distances between the time they are calculated and when they are used.
+    private int mAnimDx;
+    private int mAnimDy;
 
     /** Is the next animation to be started a window move animation? */
-    boolean mAnimateMove = false;
-
-    /** Are we currently running a window move animation? */
-    boolean mAnimatingMove = false;
+    private boolean mAnimateMove = false;
 
     float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
     float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
 
     boolean mHaveMatrix;
 
-    // For debugging, this is the last information given to the surface flinger.
-    boolean mSurfaceShown;
-    float mSurfaceX, mSurfaceY;
-    float mSurfaceW, mSurfaceH;
-    int mSurfaceLayer;
-    float mSurfaceAlpha;
-
     // Set to true if, when the window gets displayed, it should perform
     // an enter animation.
     boolean mEnterAnimationPending;
@@ -172,11 +164,6 @@
     /** Set when the window has been shown in the screen the first time. */
     static final int HAS_DRAWN = 4;
 
-    // Surface flinger doesn't support crop rectangles where width or height is non-positive.
-    // However, we need to somehow handle the situation where the cropping would completely hide
-    // the window. We achieve this by explicitly hiding the surface and not letting it be shown.
-    private boolean mHiddenForCrop;
-
     String drawStateToString() {
         switch (mDrawState) {
             case NO_SURFACE: return "NO_SURFACE";
@@ -194,6 +181,8 @@
 
     int mAttrType;
 
+    private final Rect mTmpSize = new Rect();
+
     WindowStateAnimator(final WindowState win) {
         final WindowManagerService service = win.mService;
 
@@ -204,8 +193,8 @@
         final DisplayContent displayContent = win.getDisplayContent();
         if (displayContent != null) {
             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-            mAnimDw = displayInfo.appWidth;
-            mAnimDh = displayInfo.appHeight;
+            mAnimDx = displayInfo.appWidth;
+            mAnimDy = displayInfo.appHeight;
         } else {
             Slog.w(TAG, "WindowStateAnimator ctor: Display has been removed");
             // This is checked on return and dealt with.
@@ -305,19 +294,19 @@
                         TAG, "Starting animation in " + this +
                         " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
                         " wh=" + mWin.mFrame.height() +
-                        " dw=" + mAnimDw + " dh=" + mAnimDh +
+                        " dx=" + mAnimDx + " dy=" + mAnimDy +
                         " scale=" + mService.getWindowAnimationScaleLocked());
                     final DisplayInfo displayInfo = displayContent.getDisplayInfo();
                     if (mAnimateMove) {
                         mAnimateMove = false;
                         mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
-                                mAnimDw, mAnimDh);
+                                mAnimDx, mAnimDy);
                     } else {
                         mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
                                 displayInfo.appWidth, displayInfo.appHeight);
                     }
-                    mAnimDw = displayInfo.appWidth;
-                    mAnimDh = displayInfo.appHeight;
+                    mAnimDx = displayInfo.appWidth;
+                    mAnimDy = displayInfo.appHeight;
                     mAnimation.setStartTime(mAnimationStartTime != -1
                             ? mAnimationStartTime
                             : currentTime);
@@ -374,7 +363,6 @@
 
         mAnimating = false;
         mKeyguardGoingAwayAnimation = false;
-        mAnimatingMove = false;
         mLocalAnimating = false;
         if (mAnimation != null) {
             mAnimation.cancel();
@@ -437,18 +425,23 @@
             mWin.mChildWindows.get(i).mWinAnimator.finishExit();
         }
 
-        if (mEnteringAnimation && mWin.mAppToken == null) {
-            try {
-                mEnteringAnimation = false;
-                mWin.mClient.dispatchWindowShown();
-            } catch (RemoteException e) {
+        if (mEnteringAnimation) {
+            mEnteringAnimation = false;
+            mService.requestTraversal();
+            // System windows don't have an activity and an app token as a result, but need a way
+            // to be informed about their entrance animation end.
+            if (mWin.mAppToken == null) {
+                try {
+                    mWin.mClient.dispatchWindowShown();
+                } catch (RemoteException e) {
+                }
             }
         }
 
         if (!isWindowAnimating()) {
             //TODO (multidisplay): Accessibility is supported only for the default display.
             if (mService.mAccessibilityController != null
-                    && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                    && mWin.getDisplayId() == DEFAULT_DISPLAY) {
                 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
             }
         }
@@ -464,12 +457,10 @@
         if (WindowManagerService.localLOGV) Slog.v(
                 TAG, "Exit animation finished in " + this
                 + ": remove=" + mWin.mRemoveOnExit);
-        if (mSurfaceControl != null) {
+        if (mSurfaceController != null && mSurfaceController.hasSurface()) {
             mService.mDestroySurface.add(mWin);
             mWin.mDestroying = true;
-            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(
-                mWin, "HIDE (finishExit)", null);
-            hide();
+            hide("finishExit");
         }
         mWin.mExiting = false;
         if (mWin.mRemoveOnExit) {
@@ -479,19 +470,12 @@
         mWallpaperControllerLocked.hideWallpapers(mWin);
     }
 
-    void hide() {
+    void hide(String reason) {
         if (!mLastHidden) {
             //dump();
             mLastHidden = true;
-            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
-                    "HIDE (performLayout)", null);
-            if (mSurfaceControl != null) {
-                mSurfaceShown = false;
-                try {
-                    mSurfaceControl.hide();
-                } catch (RuntimeException e) {
-                    Slog.w(TAG, "Exception hiding surface in " + mWin);
-                }
+            if (mSurfaceController != null) {
+                mSurfaceController.hideInTransaction(reason);
             }
         }
     }
@@ -511,8 +495,8 @@
         }
         if (mDrawState == DRAW_PENDING) {
             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
-                Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
-                        + mSurfaceControl);
+                Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
+                        + mSurfaceController);
             if (DEBUG_STARTING_WINDOW && startingWindow) {
                 Slog.v(TAG, "Draw state now committed in " + mWin);
             }
@@ -534,7 +518,7 @@
             return false;
         }
         if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
-            Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceControl);
+            Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
         }
         mDrawState = READY_TO_SHOW;
         boolean result = false;
@@ -543,240 +527,19 @@
                 mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
             result = performShowLocked();
         }
-        if (mDestroyPreservedSurfaceUponRedraw && result) {
+        if (mDestroyPreservedSurfaceUponRedraw) {
             mService.mDestroyPreservedSurface.add(mWin);
         }
         return result;
     }
 
-    static class SurfaceTrace extends SurfaceControl {
-        private final static String SURFACE_TAG = "SurfaceTrace";
-        private final static boolean logSurfaceTrace = DEBUG_SURFACE_TRACE;
-        final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
-
-        private float mSurfaceTraceAlpha = 0;
-        private int mLayer;
-        private final PointF mPosition = new PointF();
-        private final Point mSize = new Point();
-        private final Rect mWindowCrop = new Rect();
-        private boolean mShown = false;
-        private int mLayerStack;
-        private boolean mIsOpaque;
-        private float mDsdx, mDtdx, mDsdy, mDtdy;
-        private final String mName;
-
-        public SurfaceTrace(SurfaceSession s,
-                       String name, int w, int h, int format, int flags)
-                   throws OutOfResourcesException {
-            super(s, name, w, h, format, flags);
-            mName = name != null ? name : "Not named";
-            mSize.set(w, h);
-            if (logSurfaceTrace) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.add(0, this);
-            }
-        }
-
-        @Override
-        public void setAlpha(float alpha) {
-            if (mSurfaceTraceAlpha != alpha) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
-                        ". Called by " + Debug.getCallers(3));
-                mSurfaceTraceAlpha = alpha;
-            }
-            super.setAlpha(alpha);
-        }
-
-        @Override
-        public void setLayer(int zorder) {
-            if (zorder != mLayer) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
-                        + ". Called by " + Debug.getCallers(3));
-                mLayer = zorder;
-            }
-            super.setLayer(zorder);
-
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-                int i;
-                for (i = sSurfaces.size() - 1; i >= 0; i--) {
-                    SurfaceTrace s = sSurfaces.get(i);
-                    if (s.mLayer < zorder) {
-                        break;
-                    }
-                }
-                sSurfaces.add(i + 1, this);
-            }
-        }
-
-        @Override
-        public void setPosition(float x, float y) {
-            if (x != mPosition.x || y != mPosition.y) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mPosition.set(x, y);
-            }
-            super.setPosition(x, y);
-        }
-
-        @Override
-        public void setSize(int w, int h) {
-            if (w != mSize.x || h != mSize.y) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mSize.set(w, h);
-            }
-            super.setSize(w, h);
-        }
-
-        @Override
-        public void setWindowCrop(Rect crop) {
-            if (crop != null) {
-                if (!crop.equals(mWindowCrop)) {
-                    if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setWindowCrop("
-                            + crop.toShortString() + "): OLD:" + this + ". Called by "
-                            + Debug.getCallers(3));
-                    mWindowCrop.set(crop);
-                }
-            }
-            super.setWindowCrop(crop);
-        }
-
-        @Override
-        public void setLayerStack(int layerStack) {
-            if (layerStack != mLayerStack) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mLayerStack = layerStack;
-            }
-            super.setLayerStack(layerStack);
-        }
-
-        @Override
-        public void setOpaque(boolean isOpaque) {
-            if (isOpaque != mIsOpaque) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mIsOpaque = isOpaque;
-            }
-            super.setOpaque(isOpaque);
-        }
-
-        @Override
-        public void setSecure(boolean isSecure) {
-            super.setSecure(isSecure);
-        }
-
-        @Override
-        public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-            if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
-                        + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mDsdx = dsdx;
-                mDtdx = dtdx;
-                mDsdy = dsdy;
-                mDtdy = dtdy;
-            }
-            super.setMatrix(dsdx, dtdx, dsdy, dtdy);
-        }
-
-        @Override
-        public void hide() {
-            if (mShown) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mShown = false;
-            }
-            super.hide();
-        }
-
-        @Override
-        public void show() {
-            if (!mShown) {
-                if (logSurfaceTrace) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mShown = true;
-            }
-            super.show();
-        }
-
-        @Override
-        public void destroy() {
-            super.destroy();
-            if (logSurfaceTrace) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-            }
-        }
-
-        @Override
-        public void release() {
-            super.release();
-            if (logSurfaceTrace) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-            }
-        }
-
-        static void dumpAllSurfaces(PrintWriter pw, String header) {
-            synchronized (sSurfaces) {
-                final int N = sSurfaces.size();
-                if (N <= 0) {
-                    return;
-                }
-                if (header != null) {
-                    pw.println(header);
-                }
-                pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
-                for (int i = 0; i < N; i++) {
-                    SurfaceTrace s = sSurfaces.get(i);
-                    pw.print("  Surface #"); pw.print(i); pw.print(": #");
-                            pw.print(Integer.toHexString(System.identityHashCode(s)));
-                            pw.print(" "); pw.println(s.mName);
-                    pw.print("    mLayerStack="); pw.print(s.mLayerStack);
-                            pw.print(" mLayer="); pw.println(s.mLayer);
-                    pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
-                            pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
-                            pw.println(s.mIsOpaque);
-                    pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
-                            pw.print(s.mPosition.y);
-                            pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
-                            pw.println(s.mSize.y);
-                    pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
-                    pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
-                            pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
-                            pw.print(", "); pw.print(s.mDtdy); pw.println(")");
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
-                    + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
-                    + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
-                    + " " + mSize.x + "x" + mSize.y
-                    + " crop=" + mWindowCrop.toShortString()
-                    + " opaque=" + mIsOpaque
-                    + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
-        }
-    }
-
     void preserveSurfaceLocked() {
         if (mDestroyPreservedSurfaceUponRedraw) {
             return;
         }
-        if (mSurfaceControl != null) {
-            SurfaceControl.openTransaction();
-            try {
-                mSurfaceControl.setLayer(WINDOW_FREEZE_LAYER);
-            } finally {
-                SurfaceControl.closeTransaction();
-            }
+        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", null);
+        if (mSurfaceController != null) {
+            mSurfaceController.setLayer(mAnimLayer + 1);
         }
         mDestroyPreservedSurfaceUponRedraw = true;
         mSurfaceDestroyDeferred = true;
@@ -791,9 +554,9 @@
         mDestroyPreservedSurfaceUponRedraw = false;
     }
 
-    SurfaceControl createSurfaceLocked() {
+    WindowSurfaceController createSurfaceLocked() {
         final WindowState w = mWin;
-        if (mSurfaceControl == null) {
+        if (mSurfaceController == null) {
             if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
                     "createSurface " + this + ": mDrawState=DRAW_PENDING");
             mDrawState = DRAW_PENDING;
@@ -817,61 +580,20 @@
                 flags |= SurfaceControl.SECURE;
             }
 
-            float left = w.mFrame.left + w.mXOffset;
-            float top = w.mFrame.top + w.mYOffset;
-
-            int width;
-            int height;
-            if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
-                // for a scaled surface, we always want the requested
-                // size.
-                width = w.mRequestedWidth;
-                height = w.mRequestedHeight;
-            } else {
-                // When we're doing a drag-resizing, request a surface that's fullscreen size,
-                // so that we don't need to reallocate during the process. This also prevents
-                // buffer drops due to size mismatch.
-                final DisplayInfo displayInfo = w.getDisplayInfo();
-                if (displayInfo != null && w.isDragResizing()) {
-                    left = 0;
-                    top = 0;
-                    width = displayInfo.logicalWidth;
-                    height = displayInfo.logicalHeight;
-                } else {
-                    width = w.mCompatFrame.width();
-                    height = w.mCompatFrame.height();
-                }
-            }
-
-            // Something is wrong and SurfaceFlinger will not like this,
-            // try to revert to sane values
-            if (width <= 0) {
-                width = 1;
-            }
-            if (height <= 0) {
-                height = 1;
-            }
-
-            // Adjust for surface insets.
-            width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
-            height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
-            left -= attrs.surfaceInsets.left;
-            top -= attrs.surfaceInsets.top;
+            mTmpSize.set(w.mFrame.left + w.mXOffset, w.mFrame.top + w.mYOffset, 0, 0);
+            calculateSurfaceBounds(w, attrs);
+            final int width = mTmpSize.width();
+            final int height = mTmpSize.height();
 
             if (DEBUG_VISIBILITY) {
                 Slog.v(TAG, "Creating surface in session "
                         + mSession.mSurfaceSession + " window " + this
                         + " w=" + width + " h=" + height
-                        + " x=" + left + " y=" + top
+                        + " x=" + mTmpSize.left + " y=" + mTmpSize.top
                         + " format=" + attrs.format + " flags=" + flags);
             }
 
             // We may abort, so initialize to defaults.
-            mSurfaceShown = false;
-            mSurfaceLayer = 0;
-            mSurfaceAlpha = 0;
-            mSurfaceX = 0;
-            mSurfaceY = 0;
             w.mLastSystemDecorRect.set(0, 0, 0, 0);
             mHasClipRect = false;
             mClipRect.set(0, 0, 0, 0);
@@ -879,8 +601,6 @@
 
             // Set up surface control with initial size.
             try {
-                mSurfaceW = width;
-                mSurfaceH = height;
 
                 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
                 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
@@ -897,24 +617,15 @@
                     flags |= SurfaceControl.OPAQUE;
                 }
 
-                mSurfaceFormat = format;
-                if (DEBUG_SURFACE_TRACE) {
-                    mSurfaceControl = new SurfaceTrace(
-                            mSession.mSurfaceSession,
-                            attrs.getTitle().toString(),
-                            width, height, format, flags);
-                } else {
-                    mSurfaceControl = new SurfaceControl(
-                        mSession.mSurfaceSession,
+                mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
                         attrs.getTitle().toString(),
-                        width, height, format, flags);
-                }
+                        width, height, format, flags, this);
 
-                w.mHasSurface = true;
+                w.setHasSurface(true);
 
                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
                     Slog.i(TAG, "  CREATE SURFACE "
-                            + mSurfaceControl + " IN SESSION "
+                            + mSurfaceController + " IN SESSION "
                             + mSession.mSurfaceSession
                             + ": pid=" + mSession.mPid + " format="
                             + attrs.format + " flags=0x"
@@ -922,20 +633,20 @@
                             + " / " + this);
                 }
             } catch (OutOfResourcesException e) {
-                w.mHasSurface = false;
+                w.setHasSurface(false);
                 Slog.w(TAG, "OutOfResourcesException creating surface");
                 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
                 mDrawState = NO_SURFACE;
                 return null;
             } catch (Exception e) {
-                w.mHasSurface = false;
+                w.setHasSurface(false);
                 Slog.e(TAG, "Exception creating surface", e);
                 mDrawState = NO_SURFACE;
                 return null;
             }
 
             if (WindowManagerService.localLOGV) {
-                Slog.v(TAG, "Got surface: " + mSurfaceControl
+                Slog.v(TAG, "Got surface: " + mSurfaceController
                         + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
                         + ", animLayer=" + mAnimLayer);
             }
@@ -944,40 +655,72 @@
                 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
                 WindowManagerService.logSurface(w, "CREATE pos=("
                         + w.mFrame.left + "," + w.mFrame.top + ") ("
-                        + w.mCompatFrame.width() + "x" + w.mCompatFrame.height()
-                        + "), layer=" + mAnimLayer + " HIDE", null);
+                        + width + "x" + height + "), layer=" + mAnimLayer + " HIDE", null);
             }
 
             // Start a new transaction and apply position & offset.
-            SurfaceControl.openTransaction();
-            try {
-                mSurfaceX = left;
-                mSurfaceY = top;
+            final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
+            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                    "POS " + mTmpSize.left + ", " + mTmpSize.top, null);
+            mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack,
+                    mAnimLayer);
+            mLastHidden = true;
 
-                try {
-                    mSurfaceControl.setPosition(left, top);
-                    mSurfaceLayer = mAnimLayer;
-                    final DisplayContent displayContent = w.getDisplayContent();
-                    if (displayContent != null) {
-                        mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack());
-                    }
-                    mSurfaceControl.setLayer(mAnimLayer);
-                    mSurfaceControl.setAlpha(0);
-                    mSurfaceShown = false;
-                } catch (RuntimeException e) {
-                    Slog.w(TAG, "Error creating surface in " + w, e);
-                    mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
-                }
-                mLastHidden = true;
-            } finally {
-                SurfaceControl.closeTransaction();
-                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                        "<<< CLOSE TRANSACTION createSurfaceLocked");
-            }
             if (WindowManagerService.localLOGV) Slog.v(
                     TAG, "Created surface " + this);
         }
-        return mSurfaceControl;
+        return mSurfaceController;
+    }
+
+    private void calculateSurfaceBounds(WindowState w, LayoutParams attrs) {
+        if ((attrs.flags & FLAG_SCALED) != 0) {
+            // For a scaled surface, we always want the requested size.
+            mTmpSize.right = mTmpSize.left + w.mRequestedWidth;
+            mTmpSize.bottom = mTmpSize.top + w.mRequestedHeight;
+        } else {
+            // When we're doing a drag-resizing, request a surface that's fullscreen size,
+            // so that we don't need to reallocate during the process. This also prevents
+            // buffer drops due to size mismatch.
+            if (w.isDragResizing()) {
+                if (w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM) {
+                    mTmpSize.left = 0;
+                    mTmpSize.top = 0;
+                }
+                final DisplayInfo displayInfo = w.getDisplayInfo();
+                mTmpSize.right = mTmpSize.left + displayInfo.logicalWidth;
+                mTmpSize.bottom = mTmpSize.top + displayInfo.logicalHeight;
+            } else {
+                mTmpSize.right = mTmpSize.left + w.mCompatFrame.width();
+                mTmpSize.bottom = mTmpSize.top + w.mCompatFrame.height();
+            }
+        }
+
+        // Something is wrong and SurfaceFlinger will not like this, try to revert to sane values.
+        if (mTmpSize.width() < 1) {
+            Slog.w(TAG, "Width of " + w + " is not positive " + mTmpSize.width());
+            mTmpSize.right = mTmpSize.left + 1;
+        }
+        if (mTmpSize.height() < 1) {
+            Slog.w(TAG, "Height of " + w + " is not positive " + mTmpSize.height());
+            mTmpSize.bottom = mTmpSize.top + 1;
+        }
+
+        final int displayId = w.getDisplayId();
+        float scale = 1.0f;
+        // Magnification is supported only for the default display.
+        if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
+            final MagnificationSpec spec =
+                    mService.mAccessibilityController.getMagnificationSpecForWindowLocked(w);
+            if (spec != null && !spec.isNop()) {
+                scale = spec.scale;
+            }
+        }
+
+        // Adjust for surface insets.
+        mTmpSize.left -= scale * attrs.surfaceInsets.left;
+        mTmpSize.top -= scale * attrs.surfaceInsets.top;
+        mTmpSize.right += scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right);
+        mTmpSize.bottom += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
     }
 
     void destroySurfaceLocked() {
@@ -990,7 +733,7 @@
             }
         }
 
-        if (mSurfaceControl != null) {
+        if (mSurfaceController != null) {
             int i = mWin.mChildWindows.size();
             while (i > 0) {
                 i--;
@@ -1006,10 +749,10 @@
                         e.fillInStackTrace();
                     }
                     Slog.w(TAG, "Window " + this + " destroying surface "
-                            + mSurfaceControl + ", session " + mSession, e);
+                            + mSurfaceController + ", session " + mSession, e);
                 }
                 if (mSurfaceDestroyDeferred) {
-                    if (mSurfaceControl != null && mPendingDestroySurface != mSurfaceControl) {
+                    if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
                         if (mPendingDestroySurface != null) {
                             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
                                 RuntimeException e = null;
@@ -1019,9 +762,9 @@
                                 }
                                 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
                             }
-                            mPendingDestroySurface.destroy();
+                            mPendingDestroySurface.destroyInTransaction();
                         }
-                        mPendingDestroySurface = mSurfaceControl;
+                        mPendingDestroySurface = mSurfaceController;
                     }
                 } else {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
@@ -1030,20 +773,29 @@
                             e = new RuntimeException();
                             e.fillInStackTrace();
                         }
-                        WindowManagerService.logSurface(mWin, "DESTROY", e);
+                        WindowManagerService.logSurface(mWin, "DESTROY", null);
                     }
-                    mSurfaceControl.destroy();
+                    destroySurface();
                 }
-                mWallpaperControllerLocked.hideWallpapers(mWin);
+                // Don't hide wallpaper if we're deferring the surface destroy
+                // because of a surface change.
+                if (!(mSurfaceDestroyDeferred && mDestroyPreservedSurfaceUponRedraw)) {
+                    mWallpaperControllerLocked.hideWallpapers(mWin);
+                }
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Exception thrown when destroying Window " + this
-                    + " surface " + mSurfaceControl + " session " + mSession
+                    + " surface " + mSurfaceController + " session " + mSession
                     + ": " + e.toString());
             }
 
-            mSurfaceShown = false;
-            mSurfaceControl = null;
-            mWin.mHasSurface = false;
+            // Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
+            // needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
+            // so it can be recreated successfully in mPendingDestroySurface case.
+            mWin.setHasSurface(false);
+            if (mSurfaceController != null) {
+                mSurfaceController.setShown(false);
+            }
+            mSurfaceController = null;
             mDrawState = NO_SURFACE;
         }
     }
@@ -1059,8 +811,12 @@
                     }
                     WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
                 }
-                mPendingDestroySurface.destroy();
-                mWallpaperControllerLocked.hideWallpapers(mWin);
+                mPendingDestroySurface.destroyInTransaction();
+                // Don't hide wallpaper if we're destroying a deferred surface
+                // after a surface mode change.
+                if (!mDestroyPreservedSurfaceUponRedraw) {
+                    mWallpaperControllerLocked.hideWallpapers(mWin);
+                }
             }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Exception thrown when destroying Window "
@@ -1156,7 +912,7 @@
             tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
 
             //TODO (multidisplay): Magnification is supported only for the default display.
-            if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
+            if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
                 MagnificationSpec spec = mService.mAccessibilityController
                         .getMagnificationSpecForWindowLocked(mWin);
                 if (spec != null && !spec.isNop()) {
@@ -1239,7 +995,7 @@
 
         MagnificationSpec spec = null;
         //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
+        if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
             spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
         }
         if (spec != null) {
@@ -1334,7 +1090,7 @@
         } else if (w.mDecorFrame.isEmpty()) {
             // Windows without policy decor aren't cropped.
             w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
-        } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.mAnimating) {
+        } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.isAnimating()) {
             // If we're animating, the wallpaper crop should only be updated at the end of the
             // animation.
             mTmpClipRect.set(w.mSystemDecorRect);
@@ -1346,8 +1102,10 @@
         }
 
         final boolean fullscreen = w.isFullscreen(displayInfo.appWidth, displayInfo.appHeight);
+        final boolean isFreeformResizing =
+                w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
         final Rect clipRect = mTmpClipRect;
-        if (w.isDragResizing()) {
+        if (isFreeformResizing) {
             // When we're doing a drag-resizing, the surface is set up to cover full screen.
             // Set the clip rect to be the same size so that we don't get any scaling.
             clipRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
@@ -1372,168 +1130,74 @@
         // The clip rect was generated assuming (0,0) as the window origin,
         // so we need to translate to match the actual surface coordinates.
         clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
-        // We don't want to clip to stack bounds windows that are currently doing entrance
-        // animation for docked window, otherwise the animating window will be suddenly cut off.
 
-        if (!(mAnimator.mAnimating && w.inDockedWorkspace())) {
-            adjustCropToStackBounds(w, clipRect);
-        }
+        adjustCropToStackBounds(w, clipRect, isFreeformResizing);
 
         w.transformFromScreenToSurfaceSpace(clipRect);
 
         if (!clipRect.equals(mLastClipRect)) {
             mLastClipRect.set(clipRect);
-            try {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "CROP " + clipRect.toShortString(), null);
-                if (clipRect.width() > 0 && clipRect.height() > 0) {
-                    mSurfaceControl.setWindowCrop(clipRect);
-                    mHiddenForCrop = false;
-                } else {
-                    hide();
-                    mHiddenForCrop = true;
-                }
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error setting crop surface of " + w
-                        + " crop=" + clipRect.toShortString(), e);
-                if (!recoveringMemory) {
-                    mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
-                }
-            }
+            mSurfaceController.setCropInTransaction(clipRect, recoveringMemory);
         }
     }
 
-    private void adjustCropToStackBounds(WindowState w, Rect clipRect) {
+    private void adjustCropToStackBounds(WindowState w, Rect clipRect, boolean isFreeformResizing) {
         final AppWindowToken appToken = w.mAppToken;
         final Task task = w.getTask();
-        // We don't apply the the stack bounds to the window that is being replaced, because it was
-        // living in a different stack. If we suddenly crop it to the new stack bounds, it might
-        // get cut off. We don't want it to happen, so we let it ignore the stack bounds until it
-        // gets removed. The window that will replace it will abide them.
-        if (task != null && appToken.mCropWindowsToStack && !appToken.mWillReplaceWindow) {
-            TaskStack stack = task.mStack;
-            stack.getBounds(mTmpStackBounds);
-            // When we resize we use the big surface approach, which means we can't trust the
-            // window frame bounds anymore. Instead, the window will be placed at 0, 0, but to avoid
-            // hardcoding it, we use surface coordinates.
-            final boolean isResizing = w.isDragResizing();
-            final int frameX = isResizing ? (int) mSurfaceX :
-                    w.mFrame.left + mWin.mXOffset - w.getAttrs().surfaceInsets.left;
-            final int frameY = isResizing ? (int) mSurfaceY :
-                    w.mFrame.top + mWin.mYOffset - w.getAttrs().surfaceInsets.top;
-            // We need to do some acrobatics with surface position, because their clip region is
-            // relative to the inside of the surface, but the stack bounds aren't.
-            clipRect.left = Math.max(0,
-                    Math.max(mTmpStackBounds.left, frameX + clipRect.left) - frameX);
-            clipRect.top = Math.max(0,
-                    Math.max(mTmpStackBounds.top, frameY + clipRect.top) - frameY);
-            clipRect.right = Math.max(0,
-                    Math.min(mTmpStackBounds.right, frameX + clipRect.right) - frameX);
-            clipRect.bottom = Math.max(0,
-                    Math.min(mTmpStackBounds.bottom, frameY + clipRect.bottom) - frameY);
+        if (task == null || !appToken.mCropWindowsToStack) {
+            return;
         }
+
+        // We don't apply the stack bounds crop if:
+        // 1. The window is currently animating docked mode, otherwise the animating window will be
+        // suddenly cut off.
+        // 2. The window that is being replaced during animation, because it was living in a
+        // different stack. If we suddenly crop it to the new stack bounds, it might get cut off.
+        // We don't want it to happen, so we let it ignore the stack bounds until it gets removed.
+        // The window that will replace it will abide them.
+        if (isAnimating() && (appToken.mWillReplaceWindow || w.inDockedWorkspace())) {
+            return;
+        }
+
+        final TaskStack stack = task.mStack;
+        stack.getDimBounds(mTmpStackBounds);
+        // When we resize we use the big surface approach, which means we can't trust the
+        // window frame bounds anymore. Instead, the window will be placed at 0, 0, but to avoid
+        // hardcoding it, we use surface coordinates.
+        final int frameX = isFreeformResizing ? (int) mSurfaceController.getX() :
+                w.mFrame.left + mWin.mXOffset - w.getAttrs().surfaceInsets.left;
+        final int frameY = isFreeformResizing ? (int) mSurfaceController.getY() :
+                w.mFrame.top + mWin.mYOffset - w.getAttrs().surfaceInsets.top;
+        // We need to do some acrobatics with surface position, because their clip region is
+        // relative to the inside of the surface, but the stack bounds aren't.
+        clipRect.left = Math.max(0,
+                Math.max(mTmpStackBounds.left, frameX + clipRect.left) - frameX);
+        clipRect.top = Math.max(0,
+                Math.max(mTmpStackBounds.top, frameY + clipRect.top) - frameY);
+        clipRect.right = Math.max(0,
+                Math.min(mTmpStackBounds.right, frameX + clipRect.right) - frameX);
+        clipRect.bottom = Math.max(0,
+                Math.min(mTmpStackBounds.bottom, frameY + clipRect.bottom) - frameY);
     }
 
     void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
         final WindowState w = mWin;
 
-        float left = w.mShownPosition.x;
-        float top = w.mShownPosition.y;
+        mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0);
+        calculateSurfaceBounds(w, w.getAttrs());
 
-        int width;
-        int height;
-        if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
-            // for a scaled surface, we always want the requested
-            // size.
-            width  = w.mRequestedWidth;
-            height = w.mRequestedHeight;
-        } else {
-            // When we're doing a drag-resizing, request a surface that's fullscreen size,
-            // so that we don't need to reallocate during the process. This also prevents
-            // buffer drops due to size mismatch.
-            final DisplayInfo displayInfo = w.getDisplayInfo();
-            if (displayInfo != null && w.isDragResizing()) {
-                left = 0;
-                top = 0;
-                width = displayInfo.logicalWidth;
-                height = displayInfo.logicalHeight;
-            } else {
-                width = w.mCompatFrame.width();
-                height = w.mCompatFrame.height();
-            }
-        }
+        mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top, recoveringMemory);
+        mSurfaceResized = mSurfaceController.setSizeInTransaction(
+                mTmpSize.width(), mTmpSize.height(),
+                mDsDx * w.mHScale, mDtDx * w.mVScale,
+                mDsDy * w.mHScale, mDtDy * w.mVScale,
+                recoveringMemory);
 
-        // Something is wrong and SurfaceFlinger will not like this,
-        // try to revert to sane values
-        if (width < 1) {
-            width = 1;
-        }
-        if (height < 1) {
-            height = 1;
-        }
-
-        // Adjust for surface insets.
-        final LayoutParams attrs = w.getAttrs();
-        final int displayId = w.getDisplayId();
-        float scale = 1.0f;
-        // Magnification is supported only for the default display.
-        if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
-            MagnificationSpec spec =
-                    mService.mAccessibilityController.getMagnificationSpecForWindowLocked(w);
-            if (spec != null && !spec.isNop()) {
-                scale = spec.scale;
-            }
-        }
-
-        width += scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right);
-        height += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
-        left -= scale * attrs.surfaceInsets.left;
-        top -= scale * attrs.surfaceInsets.top;
-
-        final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
-        if (surfaceMoved) {
-            mSurfaceX = left;
-            mSurfaceY = top;
-
-            try {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "POS " + left + ", " + top, null);
-                mSurfaceControl.setPosition(left, top);
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error positioning surface of " + w
-                        + " pos=(" + left + "," + top + ")", e);
-                if (!recoveringMemory) {
-                    mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
-                }
-            }
-        }
-
-        final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
-        if (surfaceResized) {
-            mSurfaceW = width;
-            mSurfaceH = height;
-            mSurfaceResized = true;
-
-            try {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "SIZE " + width + "x" + height, null);
-                mSurfaceControl.setSize(width, height);
-                mSurfaceControl.setMatrix(
-                        mDsDx * w.mHScale, mDtDx * w.mVScale,
-                        mDsDy * w.mHScale, mDtDy * w.mVScale);
-                mAnimator.setPendingLayoutChanges(w.getDisplayId(),
-                        WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
-                w.applyDimLayerIfNeeded();
-            } catch (RuntimeException e) {
-                // If something goes wrong with the surface (such
-                // as running out of memory), don't take down the
-                // entire system.
-                Slog.e(TAG, "Error resizing surface of " + w
-                        + " size=(" + width + "x" + height + ")", e);
-                if (!recoveringMemory) {
-                    mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
-                }
-            }
+        if (mSurfaceResized) {
+            mReportSurfaceResized = true;
+            mAnimator.setPendingLayoutChanges(w.getDisplayId(),
+                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
+            w.applyDimLayerIfNeeded();
         }
 
         updateSurfaceWindowCrop(recoveringMemory);
@@ -1541,7 +1205,7 @@
 
     void prepareSurfaceLocked(final boolean recoveringMemory) {
         final WindowState w = mWin;
-        if (mSurfaceControl == null) {
+        if (mSurfaceController == null || !mSurfaceController.hasSurface()) {
             if (w.mOrientationChanging) {
                 if (DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Orientation change skips hidden " + w);
@@ -1559,9 +1223,9 @@
 
         if (mIsWallpaper && !mWin.mWallpaperVisible) {
             // Wallpaper is no longer visible and there is no wp target => hide it.
-            hide();
+            hide("prepareSurfaceLocked");
         } else if (w.mAttachedHidden || !w.isOnScreen()) {
-            hide();
+            hide("prepareSurfaceLocked");
             mWallpaperControllerLocked.hideWallpapers(w);
 
             // If we are waiting for this window to handle an
@@ -1594,51 +1258,38 @@
             w.mLastHScale = w.mHScale;
             w.mLastVScale = w.mVScale;
             if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                    "control=" + mSurfaceControl +
+                    "controller=" + mSurfaceController +
                     "alpha=" + mShownAlpha + " layer=" + mAnimLayer
                     + " matrix=[" + mDsDx + "*" + w.mHScale
                     + "," + mDtDx + "*" + w.mVScale
                     + "][" + mDsDy + "*" + w.mHScale
                     + "," + mDtDy + "*" + w.mVScale + "]", null);
-            if (mSurfaceControl != null) {
-                try {
-                    mSurfaceAlpha = mShownAlpha;
-                    mSurfaceControl.setAlpha(mShownAlpha);
-                    mSurfaceLayer = mAnimLayer;
-                    mSurfaceControl.setLayer(mAnimLayer);
-                    mSurfaceControl.setMatrix(
-                            mDsDx * w.mHScale, mDtDx * w.mVScale,
-                            mDsDy * w.mHScale, mDtDy * w.mVScale);
 
-                    if (mLastHidden && mDrawState == HAS_DRAWN && !mHiddenForCrop) {
-                        if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                                "SHOW (performLayout)", null);
-                        if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
-                                + " during relayout");
-                        if (showSurfaceRobustlyLocked()) {
-                            mLastHidden = false;
-                            if (mIsWallpaper) {
-                                mWallpaperControllerLocked.dispatchWallpaperVisibility(w, true);
-                            }
-                            // This draw means the difference between unique content and mirroring.
-                            // Run another pass through performLayout to set mHasContent in the
-                            // LogicalDisplay.
-                            mAnimator.setPendingLayoutChanges(w.getDisplayId(),
-                                    WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
-                        } else {
-                            w.mOrientationChanging = false;
-                        }
+            boolean prepared =
+                mSurfaceController.prepareToShowInTransaction(mShownAlpha, mAnimLayer,
+                        mDsDx * w.mHScale, mDtDx * w.mVScale,
+                        mDsDy * w.mHScale, mDtDy * w.mVScale,
+                        recoveringMemory);
+
+            if (prepared && mLastHidden && mDrawState == HAS_DRAWN) {
+                if (showSurfaceRobustlyLocked()) {
+                    mAnimator.requestRemovalOfReplacedWindows(w);
+                    mLastHidden = false;
+                    if (mIsWallpaper) {
+                        mWallpaperControllerLocked.dispatchWallpaperVisibility(w, true);
                     }
-                    if (mSurfaceControl != null) {
-                        w.mToken.hasVisible = true;
-                    }
-                } catch (RuntimeException e) {
-                    Slog.w(TAG, "Error updating surface in " + w, e);
-                    if (!recoveringMemory) {
-                        mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
-                    }
+                    // This draw means the difference between unique content and mirroring.
+                    // Run another pass through performLayout to set mHasContent in the
+                    // LogicalDisplay.
+                    mAnimator.setPendingLayoutChanges(w.getDisplayId(),
+                            WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
+                } else {
+                    w.mOrientationChanging = false;
                 }
             }
+            if (mSurfaceController != null && mSurfaceController.hasSurface()) {
+                w.mToken.hasVisible = true;
+            }
         } else {
             if (DEBUG_ANIM && isAnimating()) {
                 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
@@ -1663,52 +1314,31 @@
     }
 
     void setTransparentRegionHintLocked(final Region region) {
-        if (mSurfaceControl == null) {
+        if (mSurfaceController == null) {
             Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
             return;
         }
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
-        SurfaceControl.openTransaction();
-        try {
-            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
-                    "transparentRegionHint=" + region, null);
-            mSurfaceControl.setTransparentRegionHint(region);
-        } finally {
-            SurfaceControl.closeTransaction();
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                    "<<< CLOSE TRANSACTION setTransparentRegion");
-        }
+        mSurfaceController.setTransparentRegionHint(region);
     }
 
     void setWallpaperOffset(Point shownPosition) {
         final LayoutParams attrs = mWin.getAttrs();
         final int left = shownPosition.x - attrs.surfaceInsets.left;
         final int top = shownPosition.y - attrs.surfaceInsets.top;
-        if (mSurfaceX != left || mSurfaceY != top) {
-            if (mAnimating) {
-                // If this window (or its app token) is animating, then the position
-                // of the surface will be re-computed on the next animation frame.
-                // We can't poke it directly here because it depends on whatever
-                // transformation is being applied by the animation.
-                return;
-            }
-            mSurfaceX = left;
-            mSurfaceY = top;
+
+        try {
             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
             SurfaceControl.openTransaction();
-            try {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
-                        "POS " + left + ", " + top, null);
-                mSurfaceControl.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
-                updateSurfaceWindowCrop(false);
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error positioning surface of " + mWin
-                        + " pos=(" + left + "," + top + ")", e);
-            } finally {
-                SurfaceControl.closeTransaction();
-                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                        "<<< CLOSE TRANSACTION setWallpaperOffset");
-            }
+            mSurfaceController.setPositionInTransaction(mWin.mFrame.left + left,
+                    mWin.mFrame.top + top, false);
+            updateSurfaceWindowCrop(false);
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Error positioning surface of " + mWin
+                    + " pos=(" + left + "," + top + ")", e);
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                    "<<< CLOSE TRANSACTION setWallpaperOffset");
         }
     }
 
@@ -1720,7 +1350,7 @@
      * @return True if format was succesfully changed, false otherwise
      */
     boolean tryChangeFormatInPlaceLocked() {
-        if (mSurfaceControl == null) {
+        if (mSurfaceController == null) {
             return false;
         }
         final LayoutParams attrs = mWin.getAttrs();
@@ -1734,35 +1364,17 @@
     }
 
     void setOpaqueLocked(boolean isOpaque) {
-        if (mSurfaceControl == null) {
+        if (mSurfaceController == null) {
             return;
         }
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
-        SurfaceControl.openTransaction();
-        try {
-            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isOpaque=" + isOpaque,
-                    null);
-            mSurfaceControl.setOpaque(isOpaque);
-        } finally {
-            SurfaceControl.closeTransaction();
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
-        }
+        mSurfaceController.setOpaque(isOpaque);
     }
 
     void setSecureLocked(boolean isSecure) {
-        if (mSurfaceControl == null) {
+        if (mSurfaceController == null) {
             return;
         }
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
-        SurfaceControl.openTransaction();
-        try {
-            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isSecure=" + isSecure,
-                    null);
-            mSurfaceControl.setSecure(isSecure);
-        } finally {
-            SurfaceControl.closeTransaction();
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
-        }
+        mSurfaceController.setSecure(isSecure);
     }
 
     // This must be called while inside a transaction.
@@ -1811,7 +1423,7 @@
             // Force the show in the next prepareSurfaceLocked() call.
             mLastAlpha = -1;
             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
-                Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
+                Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + mWin);
             mDrawState = HAS_DRAWN;
             mService.scheduleAnimationLocked();
 
@@ -1821,7 +1433,7 @@
                 WindowState c = mWin.mChildWindows.get(i);
                 if (c.mAttachedHidden) {
                     c.mAttachedHidden = false;
-                    if (c.mWinAnimator.mSurfaceControl != null) {
+                    if (c.mWinAnimator.mSurfaceController != null) {
                         c.mWinAnimator.performShowLocked();
                         // It hadn't been shown, which means layout not
                         // performed on it, so now we want to make sure to
@@ -1857,12 +1469,8 @@
                 }
                 mWin.mAppToken.updateReportedVisibilityLocked();
             }
-
-            mWin.maybeRemoveReplacedWindow();
-
             return true;
         }
-
         return false;
     }
 
@@ -1875,22 +1483,16 @@
      * @return Returns true if the surface was successfully shown.
      */
     private boolean showSurfaceRobustlyLocked() {
-        try {
-            mSurfaceShown = true;
-            mSurfaceControl.show();
-            if (mWin.mTurnOnScreen) {
-                if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
-                mWin.mTurnOnScreen = false;
-                mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
-            }
-            return true;
-        } catch (RuntimeException e) {
-            Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + mWin, e);
+        boolean shown = mSurfaceController.showRobustlyInTransaction();
+        if (!shown)
+            return false;
+
+        if (mWin.mTurnOnScreen) {
+            if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
+            mWin.mTurnOnScreen = false;
+            mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
         }
-
-        mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
-
-        return false;
+        return true;
     }
 
     void applyEnterAnimationLocked() {
@@ -1904,7 +1506,7 @@
         applyAnimationLocked(transit, true);
         //TODO (multidisplay): Magnification is supported only for the default display.
         if (mService.mAccessibilityController != null
-                && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                && mWin.getDisplayId() == DEFAULT_DISPLAY) {
             mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
         }
     }
@@ -2005,7 +1607,7 @@
         fadeOut.setDuration(fadeDuration);
         fadeOut.setStartOffset(elapsed);
         newAnimation.addAnimation(fadeOut);
-        newAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDw, mAnimDh);
+        newAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDx, mAnimDy);
         mAnimation = newAnimation;
     }
 
@@ -2024,21 +1626,14 @@
                     pw.print(" "); mTransformation.printShortString(pw);
                     pw.println();
         }
-        if (mSurfaceControl != null) {
-            if (dumpAll) {
-                pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
-                pw.print(prefix); pw.print("mDrawState=");
-                pw.print(drawStateToString());
-                pw.print(" mLastHidden="); pw.println(mLastHidden);
-            }
-            pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
-                    pw.print(" layer="); pw.print(mSurfaceLayer);
-                    pw.print(" alpha="); pw.print(mSurfaceAlpha);
-                    pw.print(" rect=("); pw.print(mSurfaceX);
-                    pw.print(","); pw.print(mSurfaceY);
-                    pw.print(") "); pw.print(mSurfaceW);
-                    pw.print(" x "); pw.println(mSurfaceH);
+        if (mSurfaceController != null) {
+            mSurfaceController.dump(pw, prefix, dumpAll);
         }
+        if (dumpAll) {
+            pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
+            pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
+        }
+
         if (mPendingDestroySurface != null) {
             pw.print(prefix); pw.print("mPendingDestroySurface=");
                     pw.println(mPendingDestroySurface);
@@ -2070,4 +1665,29 @@
         sb.append('}');
         return sb.toString();
     }
+
+    void reclaimSomeSurfaceMemory(String operation, boolean secure) {
+        mService.reclaimSomeSurfaceMemoryLocked(this, operation, secure);
+    }
+
+    boolean getShown() {
+        if (mSurfaceController != null) {
+            return mSurfaceController.getShown();
+        }
+        return false;
+    }
+
+    void destroySurface() {
+        mSurfaceController.destroyInTransaction();
+        mSurfaceController = null;
+    }
+
+    void setMoveAnimation(int left, int top) {
+        final Animation a = AnimationUtils.loadAnimation(mContext,
+                com.android.internal.R.anim.window_move_from_decor);
+        setAnimation(a);
+        mAnimDx = mWin.mLastFrame.left - left;
+        mAnimDy = mWin.mLastFrame.top - top;
+        mAnimateMove = true;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
new file mode 100644
index 0000000..f8b8d6c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -0,0 +1,610 @@
+/*
+ * 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.wm;
+
+import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerService.HIDE_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.Debug;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+import android.view.WindowContentFrameStats;
+import android.view.Surface.OutOfResourcesException;
+
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+class WindowSurfaceController {
+    static final String TAG = "WindowSurfaceController";
+
+    final WindowStateAnimator mAnimator;
+
+    private SurfaceControl mSurfaceControl;
+
+    private boolean mSurfaceShown = false;
+    private float mSurfaceX = 0;
+    private float mSurfaceY = 0;
+    private float mSurfaceW = 0;
+    private float mSurfaceH = 0;
+
+    private float mSurfaceAlpha = 0;
+
+    private int mSurfaceLayer = 0;
+
+    // Surface flinger doesn't support crop rectangles where width or height is non-positive.
+    // However, we need to somehow handle the situation where the cropping would completely hide
+    // the window. We achieve this by explicitly hiding the surface and not letting it be shown.
+    private boolean mHiddenForCrop = false;
+
+    private final String title;
+
+    public WindowSurfaceController(SurfaceSession s,
+            String name, int w, int h, int format, int flags, WindowStateAnimator animator) {
+        mAnimator = animator;
+
+        mSurfaceW = w;
+        mSurfaceH = h;
+
+        title = name;
+
+        if (DEBUG_SURFACE_TRACE) {
+            mSurfaceControl = new SurfaceTrace(
+                    s, name, w, h, format, flags);
+        } else {
+            mSurfaceControl = new SurfaceControl(
+                    s, name, w, h, format, flags);
+        }
+    }
+
+
+    void logSurface(String msg, RuntimeException where) {
+        String str = "  SURFACE " + msg + ": " + title;
+        if (where != null) {
+            Slog.i(TAG, str, where);
+        } else {
+            Slog.i(TAG, str);
+        }
+    }
+
+    void hideInTransaction(String reason) {
+        if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
+        if (mSurfaceControl != null) {
+            mSurfaceShown = false;
+            try {
+                mSurfaceControl.hide();
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Exception hiding surface in " + this);
+            }
+        }
+    }
+
+    void setPositionAndLayer(float left, float top, int layerStack, int layer) {
+        SurfaceControl.openTransaction();
+        try {
+            mSurfaceX = left;
+            mSurfaceY = top;
+
+            try {
+                mSurfaceControl.setPosition(left, top);
+                mSurfaceControl.setLayerStack(layerStack);
+
+                mSurfaceControl.setLayer(layer);
+                mSurfaceControl.setAlpha(0);
+                mSurfaceShown = false;
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Error creating surface in " + this, e);
+                mAnimator.reclaimSomeSurfaceMemory("create-init", true);
+            }
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                    "<<< CLOSE TRANSACTION setPositionAndLayer");
+        }
+    }
+
+    void destroyInTransaction() {
+        if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+            RuntimeException e = null;
+            if (!HIDE_STACK_CRAWLS) {
+                e = new RuntimeException();
+                e.fillInStackTrace();
+            }
+        }
+        try {
+            mSurfaceControl.destroy();
+            mSurfaceShown = false;
+            mSurfaceControl = null;
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Error destroying surface in: " + this, e);
+        }
+    }
+
+    void setCropInTransaction(Rect clipRect, boolean recoveringMemory) {
+        if (SHOW_TRANSACTIONS) logSurface(
+                "CROP " + clipRect.toShortString(), null);
+        try {
+            if (clipRect.width() > 0 && clipRect.height() > 0) {
+                mSurfaceControl.setWindowCrop(clipRect);
+                mHiddenForCrop = false;
+            } else {
+                hideInTransaction("setCrop");
+                mHiddenForCrop = true;
+            }
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Error setting crop surface of " + this
+                    + " crop=" + clipRect.toShortString(), e);
+            if (!recoveringMemory) {
+                mAnimator.reclaimSomeSurfaceMemory("crop", true);
+            }
+        }
+    }
+
+    void setLayer(int layer) {
+        if (mSurfaceControl != null) {
+            SurfaceControl.openTransaction();
+            try {
+                mSurfaceControl.setLayer(layer);
+            } finally {
+                SurfaceControl.closeTransaction();
+            }
+        }
+    }
+
+    void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
+        final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
+        if (surfaceMoved) {
+            mSurfaceX = left;
+            mSurfaceY = top;
+
+            try {
+                mSurfaceControl.setPosition(left, top);
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Error positioning surface of " + this
+                        + " pos=(" + left + "," + top + ")", e);
+                if (!recoveringMemory) {
+                    mAnimator.reclaimSomeSurfaceMemory("position", true);
+                }
+            }
+        }
+    }
+
+    boolean setSizeInTransaction(int width, int height, float dsdx, float dtdx, float dsdy, float dtdy,
+            boolean recoveringMemory) {
+        final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
+        if (surfaceResized) {
+            mSurfaceW = width;
+            mSurfaceH = height;
+
+            try {
+                if (SHOW_TRANSACTIONS) logSurface(
+                        "SIZE " + width + "x" + height, null);
+                mSurfaceControl.setSize(width, height);
+                mSurfaceControl.setMatrix(
+                        dsdx, dtdx, dsdy, dtdy);
+            } catch (RuntimeException e) {
+                // If something goes wrong with the surface (such
+                // as running out of memory), don't take down the
+                // entire system.
+                Slog.e(TAG, "Error resizing surface of " + title
+                        + " size=(" + width + "x" + height + ")", e);
+                if (!recoveringMemory) {
+                    mAnimator.reclaimSomeSurfaceMemory("size", true);
+                }
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy,
+            float dtdy, boolean recoveringMemory) {
+        if (mSurfaceControl != null) {
+            try {
+                mSurfaceAlpha = alpha;
+                mSurfaceControl.setAlpha(alpha);
+                mSurfaceLayer = layer;
+                mSurfaceControl.setLayer(layer);
+                mSurfaceControl.setMatrix(
+                        dsdx, dtdx, dsdy, dtdy);
+
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Error updating surface in " + title, e);
+                if (!recoveringMemory) {
+                    mAnimator.reclaimSomeSurfaceMemory("update", true);
+                }
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void setTransparentRegionHint(final Region region) {
+        if (mSurfaceControl == null) {
+            Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
+            return;
+        }
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
+        SurfaceControl.openTransaction();
+        try {
+            mSurfaceControl.setTransparentRegionHint(region);
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                    "<<< CLOSE TRANSACTION setTransparentRegion");
+        }
+    }
+
+    void setOpaque(boolean isOpaque) {
+        if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque,
+                null);
+
+        if (mSurfaceControl == null) {
+            return;
+        }
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
+        SurfaceControl.openTransaction();
+        try {
+            mSurfaceControl.setOpaque(isOpaque);
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
+        }
+    }
+
+    void setSecure(boolean isSecure) {
+        if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure,
+                null);
+
+        if (mSurfaceControl == null) {
+            return;
+        }
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
+        SurfaceControl.openTransaction();
+        try {
+            mSurfaceControl.setSecure(isSecure);
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
+        }
+    }
+
+    boolean showRobustlyInTransaction() {
+        if (SHOW_TRANSACTIONS) logSurface(
+                "SHOW (performLayout)", null);
+        if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
+                + " during relayout");
+
+        if (mHiddenForCrop) {
+            return false;
+        }
+
+        try {
+            mSurfaceShown = true;
+            mSurfaceControl.show();
+            return true;
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + this, e);
+        }
+
+        mAnimator.reclaimSomeSurfaceMemory("show", true);
+
+        return false;
+    }
+
+    void deferTransactionUntil(IBinder handle, long frame) {
+        // TODO: Logging
+        mSurfaceControl.deferTransactionUntil(handle, frame);
+    }
+
+    boolean clearWindowContentFrameStats() {
+        if (mSurfaceControl == null) {
+            return false;
+        }
+        return mSurfaceControl.clearContentFrameStats();
+    }
+
+    boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
+        if (mSurfaceControl == null) {
+            return false;
+        }
+        return mSurfaceControl.getContentFrameStats(outStats);
+    }
+
+
+    boolean hasSurface() {
+        return mSurfaceControl != null;
+    }
+
+    IBinder getHandle() {
+        if (mSurfaceControl == null) {
+            return null;
+        }
+        return mSurfaceControl.getHandle();
+    }
+
+    void getSurface(Surface outSurface) {
+        outSurface.copyFrom(mSurfaceControl);
+    }
+
+    int getLayer() {
+        return mSurfaceLayer;
+    }
+
+    boolean getShown() {
+        return mSurfaceShown;
+    }
+
+    void setShown(boolean surfaceShown) {
+        mSurfaceShown = surfaceShown;
+    }
+
+    float getX() {
+        return mSurfaceX;
+    }
+
+    float getY() {
+        return mSurfaceY;
+    }
+
+    public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+        if (dumpAll) {
+            pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
+        }
+        pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
+        pw.print(" layer="); pw.print(mSurfaceLayer);
+        pw.print(" alpha="); pw.print(mSurfaceAlpha);
+        pw.print(" rect=("); pw.print(mSurfaceX);
+        pw.print(","); pw.print(mSurfaceY);
+        pw.print(") "); pw.print(mSurfaceW);
+        pw.print(" x "); pw.println(mSurfaceH);
+    }
+
+    @Override
+    public String toString() {
+        return mSurfaceControl.toString();
+    }
+
+    static class SurfaceTrace extends SurfaceControl {
+        private final static String SURFACE_TAG = "SurfaceTrace";
+        private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE;
+        final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
+
+        private float mSurfaceTraceAlpha = 0;
+        private int mLayer;
+        private final PointF mPosition = new PointF();
+        private final Point mSize = new Point();
+        private final Rect mWindowCrop = new Rect();
+        private boolean mShown = false;
+        private int mLayerStack;
+        private boolean mIsOpaque;
+        private float mDsdx, mDtdx, mDsdy, mDtdy;
+        private final String mName;
+
+        public SurfaceTrace(SurfaceSession s,
+                       String name, int w, int h, int format, int flags)
+                   throws OutOfResourcesException {
+            super(s, name, w, h, format, flags);
+            mName = name != null ? name : "Not named";
+            mSize.set(w, h);
+            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
+                    + Debug.getCallers(3));
+            synchronized (sSurfaces) {
+                sSurfaces.add(0, this);
+            }
+        }
+
+        @Override
+        public void setAlpha(float alpha) {
+            if (mSurfaceTraceAlpha != alpha) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
+                        ". Called by " + Debug.getCallers(3));
+                mSurfaceTraceAlpha = alpha;
+            }
+            super.setAlpha(alpha);
+        }
+
+        @Override
+        public void setLayer(int zorder) {
+            if (zorder != mLayer) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
+                        + ". Called by " + Debug.getCallers(3));
+                mLayer = zorder;
+            }
+            super.setLayer(zorder);
+
+            synchronized (sSurfaces) {
+                sSurfaces.remove(this);
+                int i;
+                for (i = sSurfaces.size() - 1; i >= 0; i--) {
+                    SurfaceTrace s = sSurfaces.get(i);
+                    if (s.mLayer < zorder) {
+                        break;
+                    }
+                }
+                sSurfaces.add(i + 1, this);
+            }
+        }
+
+        @Override
+        public void setPosition(float x, float y) {
+            if (x != mPosition.x || y != mPosition.y) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
+                        + this + ". Called by " + Debug.getCallers(3));
+                mPosition.set(x, y);
+            }
+            super.setPosition(x, y);
+        }
+
+        @Override
+        public void setSize(int w, int h) {
+            if (w != mSize.x || h != mSize.y) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
+                        + this + ". Called by " + Debug.getCallers(3));
+                mSize.set(w, h);
+            }
+            super.setSize(w, h);
+        }
+
+        @Override
+        public void setWindowCrop(Rect crop) {
+            if (crop != null) {
+                if (!crop.equals(mWindowCrop)) {
+                    if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop("
+                            + crop.toShortString() + "): OLD:" + this + ". Called by "
+                            + Debug.getCallers(3));
+                    mWindowCrop.set(crop);
+                }
+            }
+            super.setWindowCrop(crop);
+        }
+
+        @Override
+        public void setLayerStack(int layerStack) {
+            if (layerStack != mLayerStack) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
+                        + this + ". Called by " + Debug.getCallers(3));
+                mLayerStack = layerStack;
+            }
+            super.setLayerStack(layerStack);
+        }
+
+        @Override
+        public void setOpaque(boolean isOpaque) {
+            if (isOpaque != mIsOpaque) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
+                        + this + ". Called by " + Debug.getCallers(3));
+                mIsOpaque = isOpaque;
+            }
+            super.setOpaque(isOpaque);
+        }
+
+        @Override
+        public void setSecure(boolean isSecure) {
+            super.setSecure(isSecure);
+        }
+
+        @Override
+        public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+            if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
+                        + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
+                        + Debug.getCallers(3));
+                mDsdx = dsdx;
+                mDtdx = dtdx;
+                mDsdy = dsdy;
+                mDtdy = dtdy;
+            }
+            super.setMatrix(dsdx, dtdx, dsdy, dtdy);
+        }
+
+        @Override
+        public void hide() {
+            if (mShown) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
+                        + Debug.getCallers(3));
+                mShown = false;
+            }
+            super.hide();
+        }
+
+        @Override
+        public void show() {
+            if (!mShown) {
+                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
+                        + Debug.getCallers(3));
+                mShown = true;
+            }
+            super.show();
+        }
+
+        @Override
+        public void destroy() {
+            super.destroy();
+            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
+                    + Debug.getCallers(3));
+            synchronized (sSurfaces) {
+                sSurfaces.remove(this);
+            }
+        }
+
+        @Override
+        public void release() {
+            super.release();
+            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
+                    + Debug.getCallers(3));
+            synchronized (sSurfaces) {
+                sSurfaces.remove(this);
+            }
+        }
+
+        static void dumpAllSurfaces(PrintWriter pw, String header) {
+            synchronized (sSurfaces) {
+                final int N = sSurfaces.size();
+                if (N <= 0) {
+                    return;
+                }
+                if (header != null) {
+                    pw.println(header);
+                }
+                pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
+                for (int i = 0; i < N; i++) {
+                    SurfaceTrace s = sSurfaces.get(i);
+                    pw.print("  Surface #"); pw.print(i); pw.print(": #");
+                            pw.print(Integer.toHexString(System.identityHashCode(s)));
+                            pw.print(" "); pw.println(s.mName);
+                    pw.print("    mLayerStack="); pw.print(s.mLayerStack);
+                            pw.print(" mLayer="); pw.println(s.mLayer);
+                    pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
+                            pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
+                            pw.println(s.mIsOpaque);
+                    pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
+                            pw.print(s.mPosition.y);
+                            pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
+                            pw.println(s.mSize.y);
+                    pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
+                    pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
+                            pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
+                            pw.print(", "); pw.print(s.mDtdy); pw.println(")");
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
+                    + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
+                    + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
+                    + " " + mSize.x + "x" + mSize.y
+                    + " crop=" + mWindowCrop.toShortString()
+                    + " opaque=" + mIsOpaque
+                    + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 21500c5..979f55b 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -17,7 +17,6 @@
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.WindowManagerService.DEBUG;
 import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
 import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT_REPEATS;
@@ -57,7 +56,6 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -542,11 +540,8 @@
 
         mService.scheduleAnimationLocked();
 
-        if (DEBUG_WINDOW_TRACE) {
-            Slog.e(TAG,
-                    "performSurfacePlacementInner exit: animating="
-                            + mService.mAnimator.mAnimating);
-        }
+        if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
+                "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
     }
 
     private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
@@ -682,20 +677,17 @@
                 final WindowStateAnimator winAnimator = w.mWinAnimator;
 
                 // If the window has moved due to its containing content frame changing, then
-                // notify the listeners and optionally animate it.
+                // notify the listeners and optionally animate it. Simply checking a change of
+                // position is not enough, because being move due to dock divider is not a trigger
+                // for animation.
                 if (w.hasMoved()) {
                     // Frame has moved, containing content frame has also moved, and we're not
                     // currently animating... let's do something.
                     final int left = w.mFrame.left;
                     final int top = w.mFrame.top;
-                    if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
-                        Animation a = AnimationUtils.loadAnimation(mService.mContext,
-                                com.android.internal.R.anim.window_move_from_decor);
-                        winAnimator.setAnimation(a);
-                        winAnimator.mAnimDw = w.mLastFrame.left - left;
-                        winAnimator.mAnimDh = w.mLastFrame.top - top;
-                        winAnimator.mAnimateMove = true;
-                        winAnimator.mAnimatingMove = true;
+                    if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
+                            && !w.isDragResizing()) {
+                        winAnimator.setMoveAnimation(left, top);
                     }
 
                     //TODO (multidisplay): Accessibility supported only for the default display.
@@ -772,7 +764,7 @@
                                     + ", isAnimating=" + winAnimator.isAnimating());
                             if (!w.isDrawnLw()) {
                                 Slog.v(TAG, "Not displayed: s="
-                                        + winAnimator.mSurfaceControl
+                                        + winAnimator.mSurfaceController
                                         + " pv=" + w.mPolicyVisibility
                                         + " mDrawState=" + winAnimator.drawStateToString()
                                         + " ah=" + w.mAttachedHidden
@@ -932,6 +924,13 @@
                     win.prelayout();
                     mService.mPolicy.layoutWindowLw(win, null);
                     win.mLayoutSeq = seq;
+
+                    // Window frames may have changed. Update dim layer with the new bounds.
+                    final Task task = win.getTask();
+                    if (task != null) {
+                        displayContent.mDimLayerController.updateDimLayer(task);
+                    }
+
                     if (DEBUG_LAYOUT) Slog.v(TAG,
                             "  LAYOUT: mFrame="
                             + win.mFrame + " mContainingFrame="
@@ -986,15 +985,14 @@
             }
         }
 
-        // Window frames may have changed.  Tell the input dispatcher about it.
+        // Window frames may have changed. Tell the input dispatcher about it.
         mService.mInputMonitor.setUpdateInputWindowsNeededLw();
         if (updateInputWindows) {
             mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
         }
 
         mService.mPolicy.finishLayoutLw();
-        mService.mH.obtainMessage(UPDATE_DOCKED_STACK_DIVIDER,
-                DOCK_DIVIDER_NO_FORCE_UPDATE, UNUSED, displayContent).sendToTarget();
+        mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
     }
 
     /**
@@ -1178,7 +1176,7 @@
                     ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
             SurfaceControl.openTransaction();
             try {
-                mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+                mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
             } finally {
                 SurfaceControl.closeTransaction();
                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
@@ -1191,9 +1189,13 @@
                 int layer = -1;
                 for (int j = 0; j < wtoken.windows.size(); j++) {
                     final WindowState win = wtoken.windows.get(j);
-                    // Clearing the mExiting flag before entering animation. It will be set
-                    // to true if app window is removed, or window relayout to invisible.
-                    win.mExiting = false;
+                    // Clearing the mExiting flag before entering animation. It will be set to true
+                    // if app window is removed, or window relayout to invisible. We don't want to
+                    // clear it out for windows that get replaced, because the animation depends on
+                    // the flag to remove the replaced window.
+                    if (win.mAppToken == null || !win.mAppToken.mWillReplaceWindow) {
+                        win.mExiting = false;
+                    }
                     if (win.mWinAnimator.mAnimLayer > layer) {
                         layer = win.mWinAnimator.mAnimLayer;
                     }
@@ -1233,9 +1235,7 @@
                 true /*updateInputWindows*/);
         mService.mFocusMayChange = false;
         mService.notifyActivityDrawnForKeyguard();
-        return FINISH_LAYOUT_REDO_LAYOUT
-                | FINISH_LAYOUT_REDO_CONFIG;
-
+        return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
     }
 
     private boolean transitionGoodToGo(int appsCount) {
@@ -1260,6 +1260,12 @@
                 }
             }
 
+            // We also need to wait for the specs to be fetched, if needed.
+            if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
+                return false;
+            }
+
             // If the wallpaper is visible, we need to check it's ready too.
             return !mWallpaperControllerLocked.isWallpaperVisible() ||
                     mWallpaperControllerLocked.wallpaperTransitionReady();
@@ -1453,7 +1459,7 @@
                     appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
                 }
                 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-                mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+                mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
             }
         }
     }
@@ -1467,6 +1473,7 @@
         final int taskId = appToken.mTask.mTaskId;
         Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
         if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
+            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
             return;
         }
         // This thumbnail animation is very special, we need to have
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bf7c745..c611503 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -212,8 +212,6 @@
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
-        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_UNMUTE_MICROPHONE);
-        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_ADJUST_VOLUME);
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SMS);
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_FUN);
         DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SAFE_BOOT);
@@ -1220,6 +1218,10 @@
             Settings.Secure.putInt(mContext.getContentResolver(), name, value);
         }
 
+        int settingsGlobalGetInt(String name, int def) {
+            return Settings.Global.getInt(mContext.getContentResolver(), name, def);
+        }
+
         void settingsGlobalPutInt(String name, int value) {
             Settings.Global.putInt(mContext.getContentResolver(), name, value);
         }
@@ -1610,25 +1612,17 @@
     @VisibleForTesting
     boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy,
             int userId) {
-        boolean ownsDevice = isDeviceOwner(admin.info.getComponent());
-        boolean ownsProfile = (getProfileOwner(userId) != null
-                && getProfileOwner(userId).getPackageName()
-                    .equals(admin.info.getPackageName()));
+        final boolean ownsDevice = isDeviceOwner(admin.info.getComponent(), userId);
+        final boolean ownsProfile = isProfileOwner(admin.info.getComponent(), userId);
 
         if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
-            if ((userId == UserHandle.USER_SYSTEM && ownsDevice) || (ownsDevice && ownsProfile)) {
-                return true;
-            }
+            return ownsDevice;
         } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
-            if ((userId == UserHandle.USER_SYSTEM && ownsDevice) || ownsProfile) {
-                return true;
-            }
+            // DO always has the PO power.
+            return ownsDevice || ownsProfile;
         } else {
-            if (admin.info.usesPolicy(reqPolicy)) {
-                return true;
-            }
+            return admin.info.usesPolicy(reqPolicy);
         }
-        return false;
     }
 
     void sendAdminCommandLocked(ActiveAdmin admin, String action) {
@@ -2439,8 +2433,9 @@
                 return;
             }
             if (admin.getUid() != mInjector.binderGetCallingUid()) {
-                // Active device owners must remain active admins.
-                if (isDeviceOwner(adminReceiver)) {
+                // Active device/profile owners must remain active admins.
+                if (isDeviceOwner(adminReceiver, userHandle)
+                        || isProfileOwner(adminReceiver, userHandle)) {
                     return;
                 }
                 mContext.enforceCallingOrSelfPermission(
@@ -3185,12 +3180,21 @@
     }
 
     @Override
-    public boolean resetPassword(String passwordOrNull, int flags) {
+    public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException {
         if (!mHasFeature) {
             return false;
         }
         final int userHandle = UserHandle.getCallingUserId();
-        enforceNotManagedProfile(userHandle, "reset the password");
+
+        long ident = mInjector.binderClearCallingIdentity();
+        try {
+            if (mUserManager.getCredentialOwnerProfile(userHandle) != userHandle) {
+                throw new SecurityException("You can not change password for this profile because"
+                    + " it shares the password with the owner profile");
+            }
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
+        }
 
         String password = passwordOrNull != null ? passwordOrNull : "";
 
@@ -3198,8 +3202,35 @@
         synchronized (this) {
             // This api can only be called by an active device admin,
             // so try to retrieve it to check that the caller is one.
-            getActiveAdminForCallerLocked(null,
+            final ActiveAdmin admin = getActiveAdminForCallerLocked(null,
                     DeviceAdminInfo.USES_POLICY_RESET_PASSWORD);
+            final ComponentName adminComponent = admin.info.getComponent();
+
+            // As of N, only profile owners and device owners can reset the password.
+            if (!(isProfileOwner(adminComponent, userHandle)
+                    || isDeviceOwner(adminComponent, userHandle))) {
+                final boolean preN = getTargetSdk(admin.info.getPackageName(), userHandle)
+                        < android.os.Build.VERSION_CODES.N;
+                // As of N, password resetting to empty/null is not allowed anymore.
+                // TODO Should we allow DO/PO to set an empty password?
+                if (TextUtils.isEmpty(password)) {
+                    if (!preN) {
+                        throw new SecurityException("Cannot call with null password");
+                    } else {
+                        Slog.e(LOG_TAG, "Cannot call with null password");
+                        return false;
+                    }
+                }
+                // As of N, password cannot be changed by the admin if it is already set.
+                if (isLockScreenSecureUnchecked(userHandle)) {
+                    if (!preN) {
+                        throw new SecurityException("Admin cannot change current password");
+                    } else {
+                        Slog.e(LOG_TAG, "Admin cannot change current password");
+                        return false;
+                    }
+                }
+            }
             quality = getPasswordQuality(null, userHandle);
             if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                 int realQuality = LockPatternUtils.computePasswordQuality(password);
@@ -3301,9 +3332,9 @@
 
         // Don't do this with the lock held, because it is going to call
         // back in to the service.
-        long ident = mInjector.binderClearCallingIdentity();
+        ident = mInjector.binderClearCallingIdentity();
         try {
-            LockPatternUtils utils = new LockPatternUtils(mContext);
+            LockPatternUtils utils = mInjector.newLockPatternUtils();
             if (!TextUtils.isEmpty(password)) {
                 utils.saveLockPassword(password, null, quality, userHandle);
             } else {
@@ -3328,6 +3359,15 @@
         return true;
     }
 
+    private boolean isLockScreenSecureUnchecked(int userId) {
+        long ident = mInjector.binderClearCallingIdentity();
+        try {
+            return mInjector.newLockPatternUtils().isSecure(userId);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
+        }
+    }
+
     private void setDoNotAskCredentialsOnBoot() {
         synchronized (this) {
             DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM);
@@ -3683,10 +3723,11 @@
     }
 
     @Override
-    public void wipeData(int flags, final int userHandle) {
+    public void wipeData(int flags) {
         if (!mHasFeature) {
             return;
         }
+        final int userHandle = mInjector.userHandleGetCallingUserId();
         enforceCrossUserPermission(userHandle);
         synchronized (this) {
             // This API can only be called by an active device admin,
@@ -3699,8 +3740,7 @@
             long ident = mInjector.binderClearCallingIdentity();
             try {
                 if ((flags & WIPE_RESET_PROTECTION_DATA) != 0) {
-                    if (userHandle != UserHandle.USER_SYSTEM
-                            || !isDeviceOwner(admin.info.getComponent())) {
+                    if (!isDeviceOwner(admin.info.getComponent(), userHandle)) {
                         throw new SecurityException(
                                "Only device owner admins can set WIPE_RESET_PROTECTION_DATA");
                     }
@@ -4323,7 +4363,7 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
+        final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
                     DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
@@ -4335,7 +4375,7 @@
         // Tell the user manager that the restrictions have changed.
         synchronized (mUserManagerInternal.getUserRestrictionsLock()) {
             synchronized (this) {
-                if (isDeviceOwner(who)) {
+                if (isDeviceOwner(who, userHandle)) {
                     mUserManagerInternal.updateEffectiveUserRestrictionsForAllUsersLR();
                 } else {
                     mUserManagerInternal.updateEffectiveUserRestrictionsLR(userHandle);
@@ -4497,24 +4537,17 @@
         }
     }
 
-    public boolean isDeviceOwner(ComponentName who) {
-        if (!mHasFeature) {
-            return false;
-        }
+    public boolean isDeviceOwner(ComponentName who, int userId) {
         synchronized (this) {
-            return mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerComponent().equals(who);
+            return mOwners.hasDeviceOwner()
+                    && mOwners.getDeviceOwnerUserId() == userId
+                    && mOwners.getDeviceOwnerComponent().equals(who);
         }
     }
 
-    @Override
-    public boolean isDeviceOwnerPackage(String packageName) {
-        if (!mHasFeature) {
-            return false;
-        }
-        synchronized (this) {
-            return mOwners.hasDeviceOwner()
-                    && mOwners.getDeviceOwnerComponent().getPackageName().equals(packageName);
-        }
+    public boolean isProfileOwner(ComponentName who, int userId) {
+        final ComponentName profileOwner = getProfileOwner(userId);
+        return who != null && who.equals(profileOwner);
     }
 
     @Override
@@ -4634,6 +4667,30 @@
         }
     }
 
+    @Override
+    public boolean setDeviceOwnerLockScreenInfo(ComponentName who, String info) {
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        if (!mHasFeature) {
+            return false;
+        }
+
+        synchronized (this) {
+            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            long token = mInjector.binderClearCallingIdentity();
+            try {
+                new LockPatternUtils(mContext).setDeviceOwnerInfo(info);
+            } finally {
+                mInjector.binderRestoreCallingIdentity(token);
+            }
+            return true;
+        }
+    }
+
+    @Override
+    public String getDeviceOwnerLockScreenInfo() {
+        return new LockPatternUtils(mContext).getDeviceOwnerInfo();
+    }
+
     private void clearUserPoliciesLocked(UserHandle userHandle) {
         int userId = userHandle.getIdentifier();
         // Reset some of the user-specific policies
@@ -4648,7 +4705,6 @@
             mIPackageManager.updatePermissionFlagsForAllApps(
                     PackageManager.FLAG_PERMISSION_POLICY_FIXED,
                     0  /* flagValues */, userHandle.getIdentifier());
-            // TODO This will not revert audio mute restrictions if they were set.  b/24981972
             synchronized (mUserManagerInternal.getUserRestrictionsLock()) {
                 mUserManagerInternal.updateEffectiveUserRestrictionsLR(userHandle.getIdentifier());
             }
@@ -4799,10 +4855,14 @@
         if (info.isGuest()) {
             throw new IllegalStateException("Cannot set a profile owner on a guest");
         }
-        if (getProfileOwner(userHandle) != null) {
+        if (mOwners.hasProfileOwner(userHandle)) {
             throw new IllegalStateException("Trying to set the profile owner, but profile owner "
                     + "is already set.");
         }
+        if (mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerUserId() == userHandle) {
+            throw new IllegalStateException("Trying to set the profile owner, but the user "
+                    + "already has a device owner.");
+        }
         int callingUid = mInjector.binderGetCallingUid();
         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
             if (hasUserSetupCompleted(userHandle) &&
@@ -4832,6 +4892,10 @@
             throw new IllegalStateException("Trying to set the device owner, but device owner "
                     + "is already set.");
         }
+        if (mOwners.hasProfileOwner(userId)) {
+            throw new IllegalStateException("Trying to set the device owner, but the user already "
+                    + "has a profile owner.");
+        }
         if (!mUserManager.isUserRunning(new UserHandle(userId))) {
             throw new IllegalStateException("User not running: " + userId);
         }
@@ -5599,15 +5663,13 @@
     public void setUserRestriction(ComponentName who, String key, boolean enabledFromThisOwner) {
         Preconditions.checkNotNull(who, "ComponentName is null");
         final int userHandle = mInjector.userHandleGetCallingUserId();
-        final UserHandle user = new UserHandle(userHandle);
         synchronized (mUserManagerInternal.getUserRestrictionsLock()) {
             synchronized (this) {
                 ActiveAdmin activeAdmin =
                         getActiveAdminForCallerLocked(who,
                                 DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-                final boolean isDeviceOwner = isDeviceOwner(who);
-                if (!isDeviceOwner && userHandle != UserHandle.USER_SYSTEM
-                        && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
+                final boolean isDeviceOwner = isDeviceOwner(who, userHandle);
+                if (!isDeviceOwner && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
                     throw new SecurityException(
                             "Profile owners cannot set user restriction " + key);
                 }
@@ -5641,6 +5703,16 @@
     }
 
     @Override
+    public Bundle getUserRestrictions(ComponentName who) {
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        synchronized (this) {
+            final ActiveAdmin activeAdmin =
+                    getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            return activeAdmin.userRestrictions;
+        }
+    }
+
+    @Override
     public boolean setApplicationHidden(ComponentName who, String packageName,
             boolean hidden) {
         Preconditions.checkNotNull(who, "ComponentName is null");
@@ -6090,9 +6162,8 @@
             Bundle adminExtras = new Bundle();
             adminExtras.putString(DeviceAdminReceiver.EXTRA_LOCK_TASK_PACKAGE, pkg);
             for (ActiveAdmin admin : policy.mAdminList) {
-                boolean ownsDevice = isDeviceOwner(admin.info.getComponent());
-                boolean ownsProfile = (getProfileOwner(userHandle) != null
-                        && getProfileOwner(userHandle).equals(admin.info.getPackageName()));
+                final boolean ownsDevice = isDeviceOwner(admin.info.getComponent(), userHandle);
+                final boolean ownsProfile = isProfileOwner(admin.info.getComponent(), userHandle);
                 if (ownsDevice || ownsProfile) {
                     if (isEnabled) {
                         sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_LOCK_TASK_ENTERING,
@@ -6144,13 +6215,12 @@
     @Override
     public void setSecureSetting(ComponentName who, String setting, String value) {
         Preconditions.checkNotNull(who, "ComponentName is null");
-        int callingUserId = UserHandle.getCallingUserId();
-        final ContentResolver contentResolver = mContext.getContentResolver();
+        int callingUserId = mInjector.userHandleGetCallingUserId();
 
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            if (isDeviceOwner(who)) {
+            if (isDeviceOwner(who, mInjector.userHandleGetCallingUserId())) {
                 if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) {
                     throw new SecurityException(String.format(
                             "Permission denial: Device owners cannot update %1$s", setting));
@@ -6462,13 +6532,26 @@
      * @param callerUid UID of the caller.
      * @return true if the caller is the device owner app
      */
-    private boolean isCallerDeviceOwner(int callerUid) {
-        String[] pkgs = mContext.getPackageManager().getPackagesForUid(callerUid);
-        for (String pkg : pkgs) {
-            if (isDeviceOwnerPackage(pkg)) {
-                return true;
+    @VisibleForTesting
+    boolean isCallerDeviceOwner(int callerUid) {
+        synchronized (this) {
+            if (!mOwners.hasDeviceOwner()) {
+                return false;
+            }
+            if (UserHandle.getUserId(callerUid) != mOwners.getDeviceOwnerUserId()) {
+                return false;
+            }
+            final String deviceOwnerPackageName = mOwners.getDeviceOwnerComponent()
+                    .getPackageName();
+            final String[] pkgs = mContext.getPackageManager().getPackagesForUid(callerUid);
+
+            for (String pkg : pkgs) {
+                if (deviceOwnerPackageName.equals(pkg)) {
+                    return true;
+                }
             }
         }
+
         return false;
     }
 
@@ -6548,10 +6631,8 @@
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             long ident = mInjector.binderClearCallingIdentity();
             try {
-                final ApplicationInfo ai = mIPackageManager
-                        .getApplicationInfo(packageName, 0, user.getIdentifier());
-                final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
-                if (targetSdkVersion < android.os.Build.VERSION_CODES.M) {
+                if (getTargetSdk(packageName, user.getIdentifier())
+                        < android.os.Build.VERSION_CODES.M) {
                     return false;
                 }
                 final PackageManager packageManager = mContext.getPackageManager();
@@ -6622,4 +6703,73 @@
             throw new RuntimeException("Package manager has died", re);
         }
     }
+
+    @Override
+    public boolean isProvisioningAllowed(String action) {
+        if (mOwners.hasDeviceOwner()) {
+            return false;
+        }
+        final int callingUserId = mInjector.userHandleGetCallingUserId();
+        if (DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE.equals(action)) {
+            try {
+                if (!mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
+                    return false;
+                }
+            } catch (RemoteException e) {
+                return false;
+            }
+            final long ident = mInjector.binderClearCallingIdentity();
+            try {
+                if (!mUserManager.canAddMoreManagedProfiles(callingUserId, true)) {
+                    return false;
+                }
+            } finally {
+                mInjector.binderRestoreCallingIdentity(ident);
+            }
+            return true;
+        } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE.equals(action)) {
+            return isDeviceOwnerProvisioningAllowed(callingUserId);
+        } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_USER.equals(action)) {
+            if (!UserManager.isSplitSystemUser()) {
+                // ACTION_PROVISION_MANAGED_USER only supported on split-user systems.
+                return false;
+            }
+            if (hasUserSetupCompleted(callingUserId)) {
+                return false;
+            }
+            return true;
+        } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE.equals(action)) {
+            if (!UserManager.isSplitSystemUser()) {
+                // ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE only supported on split-user systems.
+                return false;
+            }
+            return isDeviceOwnerProvisioningAllowed(callingUserId);
+        }
+        throw new IllegalArgumentException("Unknown provisioning action " + action);
+    }
+
+    private boolean isDeviceOwnerProvisioningAllowed(int callingUserId) {
+        if (getProfileOwner(callingUserId) != null) {
+            return false;
+        }
+        if (mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
+            return false;
+        }
+        if (callingUserId != UserHandle.USER_SYSTEM) {
+            // Device owner provisioning can only be initiated from system user.
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns the target sdk version number that the given packageName was built for
+     * in the given user.
+     */
+    private int getTargetSdk(String packageName, int userId) throws RemoteException {
+        final ApplicationInfo ai = mIPackageManager
+                .getApplicationInfo(packageName, 0, userId);
+        final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
+        return targetSdkVersion;
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 12b3775..ded4422 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -121,17 +121,20 @@
                 if (!legacy.delete()) {
                     Slog.e(TAG, "Failed to remove the legacy setting file");
                 }
-                return;
-            }
+            } else {
+                // No legacy file, read from the new format files.
+                new DeviceOwnerReadWriter().readFromFileLocked();
 
-            // No legacy file, read from the new format files.
-            new DeviceOwnerReadWriter().readFromFileLocked();
-
-            final List<UserInfo> users = mUserManager.getUsers();
-            for (UserInfo ui : users) {
-                new ProfileOwnerReadWriter(ui.id).readFromFileLocked();
+                final List<UserInfo> users = mUserManager.getUsers();
+                for (UserInfo ui : users) {
+                    new ProfileOwnerReadWriter(ui.id).readFromFileLocked();
+                }
             }
         }
+        if (hasDeviceOwner() && hasProfileOwner(getDeviceOwnerUserId())) {
+            Slog.w(TAG, String.format("User %d has both DO and PO, which is not supported",
+                    getDeviceOwnerUserId()));
+        }
     }
 
     String getDeviceOwnerPackageName() {
@@ -218,6 +221,10 @@
         return mDeviceOwner != null;
     }
 
+    boolean hasProfileOwner(int userId) {
+        return getProfileOwnerComponent(userId) != null;
+    }
+
     /**
      * @return true if user restrictions need to be migrated for DO.
      */
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e32af5c..2f33d7c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -407,8 +407,6 @@
         mSystemServiceManager.startService(UsageStatsService.class);
         mActivityManagerService.setUsageStatsManager(
                 LocalServices.getService(UsageStatsManagerInternal.class));
-        // Update after UsageStatsService is available, needed before performBootDexOpt.
-        mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
 
         // Tracks whether the updatable WebView is in a ready state and watches for update installs.
         mSystemServiceManager.startService(WebViewUpdateService.class);
@@ -612,11 +610,11 @@
         // as appropriate.
         mSystemServiceManager.startService(UiModeManagerService.class);
 
-        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PerformBootDexOpt");
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PerformFstrimIfNeeded");
         try {
-            mPackageManagerService.performBootDexOpt();
+            mPackageManagerService.performFstrimIfNeeded();
         } catch (Throwable e) {
-            reportWtf("performing boot dexopt", e);
+            reportWtf("performing fstrim", e);
         }
         Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
@@ -1319,4 +1317,4 @@
         Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, name);
         Slog.i(TAG, name);
     }
-}
\ No newline at end of file
+}
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 34347cf..92bd81f 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -19,14 +19,10 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
@@ -51,7 +47,6 @@
 import android.text.TextUtils;
 import android.util.SparseArray;
 
-import com.android.internal.R;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
 import com.android.server.SystemService;
@@ -527,6 +522,7 @@
                         while (iterator.hasNext()) {
                             ComponentName componentName = iterator.next();
                             if (packageName.equals(componentName.getPackageName())) {
+                                userState.removeApprovedPrintService(componentName);
                                 iterator.remove();
                                 servicesRemoved = true;
                             }
@@ -587,15 +583,29 @@
                         return;
                     }
 
-                    final int installedServiceCount = installedServices.size();
-                    for (int i = 0; i < installedServiceCount; i++) {
-                        ServiceInfo serviceInfo = installedServices.get(i).serviceInfo;
-                        ComponentName component = new ComponentName(serviceInfo.packageName,
-                                serviceInfo.name);
-                        String label = serviceInfo.loadLabel(mContext.getPackageManager())
-                                .toString();
-                        showEnableInstalledPrintServiceNotification(component, label,
-                                getChangingUserId());
+                    // Enable all added services by default
+                    synchronized (mLock) {
+                        UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+
+                        Set<ComponentName> enabledServices = userState.getEnabledServices();
+                        boolean servicesAdded = false;
+
+                        final int installedServiceCount = installedServices.size();
+                        for (int i = 0; i < installedServiceCount; i++) {
+                            ServiceInfo serviceInfo = installedServices.get(i).serviceInfo;
+                            ComponentName component = new ComponentName(serviceInfo.packageName,
+                                    serviceInfo.name);
+
+                            enabledServices.add(component);
+                            servicesAdded = true;
+                        }
+
+                        if (servicesAdded) {
+                            persistComponentNamesToSettingLocked(
+                                    Settings.Secure.ENABLED_PRINT_SERVICES, enabledServices,
+                                    getChangingUserId());
+                            userState.updateIfNeededLocked();
+                        }
                     }
                 }
 
@@ -733,43 +743,5 @@
                 Binder.restoreCallingIdentity(identity);
             }
         }
-
-        private void showEnableInstalledPrintServiceNotification(ComponentName component,
-                String label, int userId) {
-            UserHandle userHandle = new UserHandle(userId);
-
-            Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS);
-            intent.putExtra(EXTRA_PRINT_SERVICE_COMPONENT_NAME, component.flattenToString());
-
-            PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, intent,
-                    PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null,
-                    userHandle);
-
-            Context builderContext = mContext;
-            try {
-                builderContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0,
-                        userHandle);
-            } catch (NameNotFoundException e) {
-                // Ignore can't find the package the system is running as.
-            }
-            Notification.Builder builder = new Notification.Builder(builderContext)
-                    .setSmallIcon(R.drawable.ic_print)
-                    .setContentTitle(mContext.getString(R.string.print_service_installed_title,
-                            label))
-                    .setContentText(mContext.getString(R.string.print_service_installed_message))
-                    .setContentIntent(pendingIntent)
-                    .setWhen(System.currentTimeMillis())
-                    .setAutoCancel(true)
-                    .setShowWhen(true)
-                    .setColor(mContext.getColor(
-                            com.android.internal.R.color.system_notification_accent_color));
-
-            NotificationManager notificationManager = (NotificationManager) mContext
-                    .getSystemService(Context.NOTIFICATION_SERVICE);
-
-            String notificationTag = getClass().getName() + ":" + component.flattenToString();
-            notificationManager.notifyAsUser(notificationTag, 0, builder.build(),
-                    userHandle);
-        }
     }
 }
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index 85c876a..e5370f4 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -279,6 +279,35 @@
         }
     }
 
+    /**
+     * Connect to the print spooler service and remove an approved print service.
+     *
+     * @param serviceToRemove The {@link ComponentName} of the service to be removed.
+     */
+    public final void removeApprovedPrintService(ComponentName serviceToRemove) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            getRemoteInstanceLazy().removeApprovedPrintService(serviceToRemove);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error removing approved print service.", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error removing approved print service.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
+                        + "] removing approved print service()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+    }
+
     public final void removeObsoletePrintJobs() {
         throwIfCalledOnMainThread();
         synchronized (mLock) {
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index ae19dac..f37bb9eb 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -297,6 +297,15 @@
         }
     }
 
+    /**
+     * Remove an approved print service.
+     *
+     * @param serviceToRemove The {@link ComponentName} of the service to be removed.
+     */
+    public void removeApprovedPrintService(ComponentName serviceToRemove) {
+        mSpooler.removeApprovedPrintService(serviceToRemove);
+    }
+
     public void restartPrintJob(PrintJobId printJobId, int appId) {
         PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, appId);
         if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 727858b..36980e3 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -490,6 +490,17 @@
 
         assertEquals(admin1.getPackageName(), dpm.getDeviceOwner());
 
+        // Try to set a profile owner on the same user, which should fail.
+        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
+        dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM);
+        try {
+            dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM);
+            fail("IllegalStateException not thrown");
+        } catch (IllegalStateException expected) {
+            assertTrue("Message was: " + expected.getMessage(),
+                    expected.getMessage().contains("already has a device owner"));
+        }
+
         // TODO Test getDeviceOwnerName() too.  To do so, we need to change
         // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
     }
@@ -509,6 +520,8 @@
             dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"));
             fail("Didn't throw IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
+            assertTrue("Message was: " + expected.getMessage(),
+                    expected.getMessage().contains("Invalid component"));
         }
     }
 
@@ -597,6 +610,17 @@
 
     public void testSetProfileOwner() throws Exception {
         setAsProfileOwner(admin1);
+
+        // Try setting DO on the same user, which should fail.
+        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
+        dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
+        try {
+            dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE);
+            fail("IllegalStateException not thrown");
+        } catch (IllegalStateException expected) {
+            assertTrue("Message was: " + expected.getMessage(),
+                    expected.getMessage().contains("already has a profile owner"));
+        }
     }
 
     public void testSetProfileOwner_failures() throws Exception {
@@ -739,6 +763,10 @@
                 DpmTestUtils.newRestrictions(),
                 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
         );
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(),
+                dpm.getUserRestrictions(admin1)
+        );
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_SMS);
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
@@ -748,6 +776,11 @@
                         UserManager.DISALLOW_SMS, UserManager.DISALLOW_OUTGOING_CALLS),
                 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
         );
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(
+                        UserManager.DISALLOW_SMS, UserManager.DISALLOW_OUTGOING_CALLS),
+                dpm.getUserRestrictions(admin1)
+        );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_SMS);
 
@@ -755,6 +788,10 @@
                 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
                 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
         );
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
+                dpm.getUserRestrictions(admin1)
+        );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
 
@@ -762,6 +799,10 @@
                 DpmTestUtils.newRestrictions(),
                 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
         );
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(),
+                dpm.getUserRestrictions(admin1)
+        );
 
         // TODO Check inner calls.
         // TODO Make sure restrictions are written to the file.
@@ -787,6 +828,13 @@
                 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
                         .ensureUserRestrictions()
         );
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(
+                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+                        UserManager.DISALLOW_OUTGOING_CALLS
+                ),
+                dpm.getUserRestrictions(admin1)
+        );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
 
@@ -798,6 +846,12 @@
                 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
                         .ensureUserRestrictions()
         );
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(
+                        UserManager.DISALLOW_OUTGOING_CALLS
+                ),
+                dpm.getUserRestrictions(admin1)
+        );
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
 
@@ -806,6 +860,10 @@
                 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
                         .ensureUserRestrictions()
         );
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(),
+                dpm.getUserRestrictions(admin1)
+        );
 
         // TODO Check inner calls.
         // TODO Make sure restrictions are written to the file.
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 013154b..2b0919b 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -215,11 +215,11 @@
             mPowerManager = getContext().getSystemService(PowerManager.class);
 
             mScreenOnSystemTimeSnapshot = System.currentTimeMillis();
-            synchronized (this) {
+            synchronized (mLock) {
                 mScreenOnTime = readScreenOnTimeLocked();
             }
-            mDisplayManager.registerDisplayListener(mDisplayListener, null);
-            synchronized (this) {
+            mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
+            synchronized (mLock) {
                 updateDisplayLocked();
             }
         } else if (phase == PHASE_BOOT_COMPLETED) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index a96c164..f396c2d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -291,21 +291,26 @@
                 String curService = Settings.Secure.getStringForUser(
                         mResolver, Settings.Secure.VOICE_INTERACTION_SERVICE, mCurUser);
                 ComponentName serviceComponent = null;
+                ServiceInfo serviceInfo = null;
                 if (curService != null && !curService.isEmpty()) {
                     try {
                         serviceComponent = ComponentName.unflattenFromString(curService);
-                    } catch (RuntimeException e) {
+                        serviceInfo = AppGlobals.getPackageManager()
+                                .getServiceInfo(serviceComponent, 0, mCurUser);
+                    } catch (RuntimeException | RemoteException e) {
                         Slog.wtf(TAG, "Bad voice interaction service name " + curService, e);
                         serviceComponent = null;
+                        serviceInfo = null;
                     }
                 }
+
                 if (force || mImpl == null || mImpl.mUser != mCurUser
                         || !mImpl.mComponent.equals(serviceComponent)) {
                     mSoundTriggerHelper.stopAllRecognitions();
                     if (mImpl != null) {
                         mImpl.shutdownLocked();
                     }
-                    if (serviceComponent != null) {
+                    if (serviceComponent != null && serviceInfo != null) {
                         mImpl = new VoiceInteractionManagerServiceImpl(mContext,
                                 UiThread.getHandler(), this, mCurUser, serviceComponent);
                         mImpl.startLocked();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6b1b6296..3b281e2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4848,4 +4848,21 @@
         }
         return null;
     }
-}
+
+    /**
+     * Returns the service state information on specified subscription. Callers require
+     * either READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE to retrieve the information.
+     * @hide
+     */
+    public ServiceState getServiceStateForSubscriber(int subId) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getServiceStateForSubscriber(subId, getOpPackageName());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index dcece26..8172e94 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -21,9 +21,10 @@
 import android.telecom.PhoneAccount;
 import android.telephony.CellInfo;
 import android.telephony.IccOpenLogicalChannelResponse;
+import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.RadioAccessFamily;
-import android.telephony.ModemActivityInfo;
+import android.telephony.ServiceState;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.OperatorInfo;
 import java.util.List;
@@ -1005,4 +1006,12 @@
      * Return the modem activity info.
      */
     ModemActivityInfo getModemActivityInfo();
+
+    /**
+     * Get the service state on specified subscription
+     * @param subId Subscription id
+     * @param callingPackage The package making the call
+     * @return Service state on specified subscription.
+     */
+    ServiceState getServiceStateForSubscriber(int subId, String callingPackage);
 }
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index e09d124..4821678 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -177,6 +177,18 @@
     }
 
     @Override
+    public File getDeviceEncryptedFilesDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public File getCredentialEncryptedFilesDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public File getNoBackupFilesDir() {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/NetworkSecurityConfigTest/Android.mk b/tests/NetworkSecurityConfigTest/Android.mk
new file mode 100644
index 0000000..a63162d
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+LOCAL_CERTIFICATE := platform
+
+LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := NetworkSecurityConfigTests
+
+include $(BUILD_PACKAGE)
diff --git a/tests/NetworkSecurityConfigTest/AndroidManifest.xml b/tests/NetworkSecurityConfigTest/AndroidManifest.xml
new file mode 100644
index 0000000..4c1fbd3
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.security.net.config"
+          android:sharedUserId="android.uid.system">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="android.security.net.config"
+        android:label="ANSC Tests">
+    </instrumentation>
+</manifest>
diff --git a/tests/NetworkSecurityConfigTest/res/raw/ca_certs_der.der b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_der.der
new file mode 100644
index 0000000..235bd47
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_der.der
Binary files differ
diff --git a/tests/NetworkSecurityConfigTest/res/raw/ca_certs_pem.pem b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_pem.pem
new file mode 100644
index 0000000..413e3c0
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/raw/ca_certs_pem.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
+MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
+aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
+WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
+AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
+OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
+T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
+JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
+Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
+PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
+aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
+TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
+LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
+BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
+dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
+AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
+NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
+b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
+BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
+I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
+CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
+2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
+2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
+-----END CERTIFICATE-----
diff --git a/tests/NetworkSecurityConfigTest/res/raw/test_debug_ca.pem b/tests/NetworkSecurityConfigTest/res/raw/test_debug_ca.pem
new file mode 100644
index 0000000..81648d9
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/raw/test_debug_ca.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDITCCAgmgAwIBAgIJAP/YiWztz/J7MA0GCSqGSIb3DQEBCwUAMCcxFjAUBgNV
+BAMMDVRlc3QgZGVidWcgQ0ExDTALBgNVBAoMBEFPU1AwHhcNMTUxMTA5MjEyNjQ2
+WhcNMTgwODI5MjEyNjQ2WjAnMRYwFAYDVQQDDA1UZXN0IGRlYnVnIENBMQ0wCwYD
+VQQKDARBT1NQMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuPFmkOJj
+ehjfvdDr2qTcBWNqNATrW1SuM88Vj00ubUFQ4tZElozj8YnQOw1FeC79c1k88b8R
+6jcqYYp/mw2JYoD6yWcFPHo5BplIpk0EhIUARH/aeoclHvsUN2GGDyTO0vf0CfJn
+9Wp6lSLjyq7V/6tYdk+0cL632t56MHp8TCO+AaveYP1T8JZqx0/50xNcsK7lIqNa
+ctWyRGFxR4ifdVsgkw9WhAB/Ow2uOwN9uLGqzsCd+yXW2weX52EIivoTGZfJo+U8
+Fi0ygnCHBv2jsJA7yWLhHmZ4ijsVtfutIKmN0w+DHkl6S25girXhy0zJp/1QvHGm
+jaF60V1gw471jQIDAQABo1AwTjAdBgNVHQ4EFgQUoq66jncy83L5eeyW1g78s/uq
+iyQwHwYDVR0jBBgwFoAUoq66jncy83L5eeyW1g78s/uqiyQwDAYDVR0TBAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAQEAohytuH4CdX0gO8EGVDRVurRH7LO69lwd/6Iw
+hJ1lIK/mzj5RM2itVGTkintyHCLu5giVkHn4FHg4X9qzZaTPOcXv9ntQNS2nacZe
+bY8nfhsAhstJT4nIOWHE3FrZkMDOK6nZHIzfscX3V/VVq5MeA+WzXwmKp6MBNr+E
+oUegXCGjd26Bl6SFz3rD7Qh+dzSTtyf/ECzXaMjpZu3k6fb4EgRz6vdBCHKKtpv6
+Mxcr0nLwdI6LnAGXvJLV4sj+l6Ngg00EeyorG8ATgtmsUrXXOR1e+yDCQv6fjQfs
+CWYztECAUE9hfCXJwb0TBrq9YeJAvcO7iE6S0Pq+X3xNtetE1A==
+-----END CERTIFICATE-----
diff --git a/tests/NetworkSecurityConfigTest/res/xml/attributes.xml b/tests/NetworkSecurityConfigTest/res/xml/attributes.xml
new file mode 100644
index 0000000..eff13c8
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/attributes.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config cleartextTrafficPermitted="false" hstsEnforced="true">
+  </base-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_config0.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_config0.xml
new file mode 100644
index 0000000..6af855d
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/bad_config0.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+      <!-- Bad pin digest -->
+      <pin digest="I am probably not an algorithm">1HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_config1.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_config1.xml
new file mode 100644
index 0000000..d683b74
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/bad_config1.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+    <!-- Unknown pin digest -->
+      <pin>1HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_config2.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_config2.xml
new file mode 100644
index 0000000..6f3f8b4
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/bad_config2.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+      <!-- empty digest -->
+      <pin digest="SHA-256"></pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_config3.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_config3.xml
new file mode 100644
index 0000000..fb2126c
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/bad_config3.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+  </domain-config>
+  <domain-config>
+    <!-- Same domain name used in two configs -->
+    <domain>android.com</domain>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_config4.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_config4.xml
new file mode 100644
index 0000000..95972ce
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/bad_config4.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <!-- domains are not allowed in base-config -->
+    <domain>android.com</domain>
+  </base-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_config5.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_config5.xml
new file mode 100644
index 0000000..8b6b721
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/bad_config5.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <!-- pins are not allowed in base-config -->
+    <pin-set>
+    </pin-set>
+  </base-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_pin.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_pin.xml
new file mode 100644
index 0000000..62a7b88
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/bad_pin.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+      <pin digest="SHA-256">1HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/debug_basic.xml b/tests/NetworkSecurityConfigTest/res/xml/debug_basic.xml
new file mode 100644
index 0000000..8da9317
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/debug_basic.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <debug-overrides>
+    <trust-anchors>
+      <certificates src="system" />
+    </trust-anchors>
+  </debug-overrides>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/debug_domain.xml b/tests/NetworkSecurityConfigTest/res/xml/debug_domain.xml
new file mode 100644
index 0000000..24eed7a
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/debug_domain.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="@raw/ca_certs_pem" />
+    </trust-anchors>
+  </domain-config>
+  <debug-overrides>
+    <trust-anchors>
+      <certificates src="@raw/test_debug_ca" />
+    </trust-anchors>
+  </debug-overrides>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/debug_inherit.xml b/tests/NetworkSecurityConfigTest/res/xml/debug_inherit.xml
new file mode 100644
index 0000000..ce0cbc8
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/debug_inherit.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <debug-overrides>
+    <trust-anchors>
+      <certificates src="@raw/test_debug_ca" />
+    </trust-anchors>
+  </debug-overrides>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/domain1.xml b/tests/NetworkSecurityConfigTest/res/xml/domain1.xml
new file mode 100644
index 0000000..6d8565c
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/domain1.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/empty_config.xml b/tests/NetworkSecurityConfigTest/res/xml/empty_config.xml
new file mode 100644
index 0000000..1bd94b6
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/empty_config.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/empty_trust.xml b/tests/NetworkSecurityConfigTest/res/xml/empty_trust.xml
new file mode 100644
index 0000000..8093b9d
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/empty_trust.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/expired_pin.xml b/tests/NetworkSecurityConfigTest/res/xml/expired_pin.xml
new file mode 100644
index 0000000..f9f8465
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/expired_pin.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <!-- Invalid pin that has expired -->
+    <pin-set expiration="2015-01-01">
+      <pin digest="SHA-256">aaaaaaaaaaa2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/multiple_configs.xml b/tests/NetworkSecurityConfigTest/res/xml/multiple_configs.xml
new file mode 100644
index 0000000..df08467
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/multiple_configs.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+  <domain-config>
+    <domain>google.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/multiple_domains.xml b/tests/NetworkSecurityConfigTest/res/xml/multiple_domains.xml
new file mode 100644
index 0000000..9743c5f
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/multiple_domains.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <domain>google.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml b/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml
new file mode 100644
index 0000000..d45fd77
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <domain-config>
+      <domain includeSubdomains="true">android.com</domain>
+      <trust-anchors>
+          <certificates src="system" />
+      </trust-anchors>
+      <!-- nested config that adds pins -->
+      <domain-config>
+          <domain>developer.android.com</domain>
+          <pin-set>
+              <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+          </pin-set>
+      </domain-config>
+    </domain-config>
+    <base-config cleartextTrafficPermitted="false">
+    </base-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/nested_domains_override.xml b/tests/NetworkSecurityConfigTest/res/xml/nested_domains_override.xml
new file mode 100644
index 0000000..84e06e3
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/nested_domains_override.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <base-config cleartextTrafficPermitted="false">
+    </base-config>
+    <!-- Nested config that overrides parent -->
+    <domain-config cleartextTrafficPermitted="true">
+        <domain includeSubdomains="true">android.com</domain>
+        <domain-config cleartextTrafficPermitted="false">
+            <domain>developer.android.com</domain>
+        </domain-config>
+    </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/override_pins.xml b/tests/NetworkSecurityConfigTest/res/xml/override_pins.xml
new file mode 100644
index 0000000..785714a
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/override_pins.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+      <pin digest="SHA-256">aaaaaaaaIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+    <trust-anchors>
+      <certificates src="system" overridePins="true" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/pins1.xml b/tests/NetworkSecurityConfigTest/res/xml/pins1.xml
new file mode 100644
index 0000000..1773d280
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/pins1.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+      <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/resource_anchors_der.xml b/tests/NetworkSecurityConfigTest/res/xml/resource_anchors_der.xml
new file mode 100644
index 0000000..dfd6fd9
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/resource_anchors_der.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="@raw/ca_certs_der" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/resource_anchors_pem.xml b/tests/NetworkSecurityConfigTest/res/xml/resource_anchors_pem.xml
new file mode 100644
index 0000000..894f29b
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/resource_anchors_pem.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="@raw/ca_certs_pem" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/subdomains.xml b/tests/NetworkSecurityConfigTest/res/xml/subdomains.xml
new file mode 100644
index 0000000..482b26c
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/subdomains.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain includeSubdomains="true">android.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
new file mode 100644
index 0000000..9f48d56
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.app.Activity;
+import android.test.ActivityUnitTestCase;
+import android.util.ArraySet;
+import android.util.Pair;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+
+public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> {
+
+    public NetworkSecurityConfigTests() {
+        super(Activity.class);
+    }
+
+    // SHA-256 of the G2 intermediate CA for android.com (as of 10/2015).
+    private static final byte[] G2_SPKI_SHA256
+            = hexToBytes("ec722969cb64200ab6638f68ac538e40abab5b19a6485661042a1061c4612776");
+
+    private static byte[] hexToBytes(String s) {
+        int len = s.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(
+                    s.charAt(i + 1), 16));
+        }
+        return data;
+    }
+
+
+
+    /**
+     * Return a NetworkSecurityConfig that has an empty TrustAnchor set. This should always cause a
+     * SSLHandshakeException when used for a connection.
+     */
+    private NetworkSecurityConfig getEmptyConfig() {
+        return new NetworkSecurityConfig.Builder().build();
+    }
+
+    private NetworkSecurityConfig getSystemStoreConfig() {
+        return new NetworkSecurityConfig.Builder()
+                .addCertificatesEntryRef(
+                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                .build();
+    }
+
+    public void testEmptyConfig() throws Exception {
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        ConfigSource testSource =
+                new TestConfigSource(domainMap, getEmptyConfig());
+        SSLContext context = TestUtils.getSSLContext(testSource);
+        TestUtils.assertConnectionFails(context, "android.com", 443);
+    }
+
+    public void testEmptyPerNetworkSecurityConfig() throws Exception {
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", true), getEmptyConfig()));
+        NetworkSecurityConfig defaultConfig = getSystemStoreConfig();
+        SSLContext context = TestUtils.getSSLContext(new TestConfigSource(domainMap, defaultConfig));
+        TestUtils.assertConnectionFails(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "google.com", 443);
+    }
+
+    public void testBadPin() throws Exception {
+        ArraySet<Pin> pins = new ArraySet<Pin>();
+        pins.add(new Pin("SHA-256", new byte[0]));
+        NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
+                .setPinSet(new PinSet(pins, Long.MAX_VALUE))
+                .addCertificatesEntryRef(
+                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                .build();
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", true), domain));
+        SSLContext context
+                = TestUtils.getSSLContext(new TestConfigSource(domainMap, getSystemStoreConfig()));
+        TestUtils.assertConnectionFails(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "google.com", 443);
+    }
+
+    public void testGoodPin() throws Exception {
+        ArraySet<Pin> pins = new ArraySet<Pin>();
+        pins.add(new Pin("SHA-256", G2_SPKI_SHA256));
+        NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
+                .setPinSet(new PinSet(pins, Long.MAX_VALUE))
+                .addCertificatesEntryRef(
+                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                .build();
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", true), domain));
+        SSLContext context
+                = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig()));
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+    }
+
+    public void testOverridePins() throws Exception {
+        // Use a bad pin + granting the system CA store the ability to override pins.
+        ArraySet<Pin> pins = new ArraySet<Pin>();
+        pins.add(new Pin("SHA-256", new byte[0]));
+        NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
+                .setPinSet(new PinSet(pins, Long.MAX_VALUE))
+                .addCertificatesEntryRef(
+                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), true))
+                .build();
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", true), domain));
+        SSLContext context
+                = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig()));
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testMostSpecificNetworkSecurityConfig() throws Exception {
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", true), getEmptyConfig()));
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("developer.android.com", false), getSystemStoreConfig()));
+        SSLContext context
+                = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig()));
+        TestUtils.assertConnectionFails(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+    }
+
+    public void testSubdomainIncluded() throws Exception {
+        // First try connecting to a subdomain of a domain entry that includes subdomains.
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", true), getSystemStoreConfig()));
+        SSLContext context
+                = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig()));
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+        // Now try without including subdomains.
+        domainMap = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", false), getSystemStoreConfig()));
+        context = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig()));
+        TestUtils.assertConnectionFails(context, "developer.android.com", 443);
+    }
+
+    public void testConfigBuilderUsesParents() throws Exception {
+        // Check that a builder with a parent uses the parent's values when non is set.
+        NetworkSecurityConfig config = new NetworkSecurityConfig.Builder()
+                .setParent(NetworkSecurityConfig.getDefaultBuilder())
+                .build();
+        assert(!config.getTrustAnchors().isEmpty());
+    }
+
+    public void testConfigBuilderParentLoop() throws Exception {
+        NetworkSecurityConfig.Builder config1 = new NetworkSecurityConfig.Builder();
+        NetworkSecurityConfig.Builder config2 = new NetworkSecurityConfig.Builder();
+        config1.setParent(config2);
+        try {
+            config2.setParent(config1);
+            fail("Loop in NetworkSecurityConfig parents");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testWithUrlConnection() throws Exception {
+        ArraySet<Pin> pins = new ArraySet<Pin>();
+        pins.add(new Pin("SHA-256", G2_SPKI_SHA256));
+        NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
+                .setPinSet(new PinSet(pins, Long.MAX_VALUE))
+                .addCertificatesEntryRef(
+                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                .build();
+        ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
+                = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
+        domainMap.add(new Pair<Domain, NetworkSecurityConfig>(
+                new Domain("android.com", true), domain));
+        SSLContext context
+                = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig()));
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionFails(context, "google.com", 443);
+    }
+}
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
new file mode 100644
index 0000000..92eadc0
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import java.util.Set;
+import java.security.cert.X509Certificate;
+
+/** @hide */
+public class TestCertificateSource implements CertificateSource {
+
+    private final Set<X509Certificate> mCertificates;
+    public TestCertificateSource(Set<X509Certificate> certificates) {
+        mCertificates = certificates;
+    }
+
+    public Set<X509Certificate> getCertificates() {
+            return mCertificates;
+    }
+}
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestConfigSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestConfigSource.java
new file mode 100644
index 0000000..609f481
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestConfigSource.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.util.Pair;
+import java.util.Set;
+
+/** @hide */
+public class TestConfigSource implements ConfigSource {
+    private final Set<Pair<Domain, NetworkSecurityConfig>> mConfigs;
+    private final NetworkSecurityConfig mDefaultConfig;
+    public TestConfigSource(Set<Pair<Domain, NetworkSecurityConfig>> configs,
+            NetworkSecurityConfig defaultConfig) {
+        mConfigs = configs;
+        mDefaultConfig = defaultConfig;
+    }
+
+    public Set<Pair<Domain, NetworkSecurityConfig>> getPerDomainConfigs() {
+        return mConfigs;
+    }
+
+    public NetworkSecurityConfig getDefaultConfig() {
+        return mDefaultConfig;
+    }
+}
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java
new file mode 100644
index 0000000..f7590fd
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import java.net.Socket;
+import java.net.URL;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
+import junit.framework.Assert;
+
+public final class TestUtils extends Assert {
+
+    private TestUtils() {
+    }
+
+    public static void assertConnectionFails(SSLContext context, String host, int port)
+            throws Exception {
+        try {
+            Socket s = context.getSocketFactory().createSocket(host, port);
+            s.getInputStream();
+            fail("Expected connection to " + host + ":" + port + " to fail.");
+        } catch (SSLHandshakeException expected) {
+        }
+    }
+
+    public static void assertConnectionSucceeds(SSLContext context, String host, int port)
+            throws Exception {
+        Socket s = context.getSocketFactory().createSocket(host, port);
+        s.getInputStream();
+    }
+
+    public static void assertUrlConnectionFails(SSLContext context, String host, int port)
+            throws Exception {
+        URL url = new URL("https://" + host + ":" + port);
+        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+        connection.setSSLSocketFactory(context.getSocketFactory());
+        try {
+            connection.getInputStream();
+            fail("Connection to " + host + ":" + port + " expected to fail");
+        } catch (SSLHandshakeException expected) {
+            // ignored.
+        }
+    }
+
+    public static void assertUrlConnectionSucceeds(SSLContext context, String host, int port)
+            throws Exception {
+        URL url = new URL("https://" + host + ":" + port);
+        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+        connection.setSSLSocketFactory(context.getSocketFactory());
+        connection.getInputStream();
+    }
+
+    public static SSLContext getSSLContext(ConfigSource source) throws Exception {
+        ApplicationConfig config = new ApplicationConfig(source);
+        TrustManagerFactory tmf =
+                TrustManagerFactory.getInstance("PKIX", new NetworkSecurityConfigProvider());
+        tmf.init(new RootTrustManagerFactorySpi.ApplicationConfigParameters(config));
+        SSLContext context = SSLContext.getInstance("TLS");
+        context.init(null, tmf.getTrustManagers(), null);
+        return context;
+    }
+}
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
new file mode 100644
index 0000000..c6f3680
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.net.config;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.util.ArraySet;
+import android.util.Pair;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
+public class XmlConfigTests extends AndroidTestCase {
+
+    private final static String DEBUG_CA_SUBJ = "O=AOSP, CN=Test debug CA";
+
+    public void testEmptyConfigFile() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.empty_config);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertFalse(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        assertNotNull(config);
+        // Check defaults.
+        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isHstsEnforced());
+        assertFalse(config.getTrustAnchors().isEmpty());
+        PinSet pinSet = config.getPins();
+        assertTrue(pinSet.pins.isEmpty());
+        // Try some connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "google.com", 443);
+    }
+
+    public void testEmptyAnchors() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.empty_trust);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertFalse(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        assertNotNull(config);
+        // Check defaults.
+        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isHstsEnforced());
+        assertTrue(config.getTrustAnchors().isEmpty());
+        PinSet pinSet = config.getPins();
+        assertTrue(pinSet.pins.isEmpty());
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionFails(context, "android.com", 443);
+        TestUtils.assertConnectionFails(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionFails(context, "google.com", 443);
+    }
+
+    public void testBasicDomainConfig() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.domain1);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        assertNotNull(config);
+        // Check defaults.
+        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isHstsEnforced());
+        assertTrue(config.getTrustAnchors().isEmpty());
+        PinSet pinSet = config.getPins();
+        assertTrue(pinSet.pins.isEmpty());
+        // Check android.com.
+        config = appConfig.getConfigForHostname("android.com");
+        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isHstsEnforced());
+        assertFalse(config.getTrustAnchors().isEmpty());
+        pinSet = config.getPins();
+        assertTrue(pinSet.pins.isEmpty());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionFails(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionFails(context, "google.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testBasicPinning() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.pins1);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        // Check android.com.
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        PinSet pinSet = config.getPins();
+        assertFalse(pinSet.pins.isEmpty());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "google.com", 443);
+    }
+
+    public void testExpiredPin() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.expired_pin);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        // Check android.com.
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        PinSet pinSet = config.getPins();
+        assertFalse(pinSet.pins.isEmpty());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testOverridesPins() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.override_pins);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        // Check android.com.
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        PinSet pinSet = config.getPins();
+        assertFalse(pinSet.pins.isEmpty());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testBadPin() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.bad_pin);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        // Check android.com.
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        PinSet pinSet = config.getPins();
+        assertFalse(pinSet.pins.isEmpty());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionFails(context, "android.com", 443);
+        TestUtils.assertUrlConnectionFails(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "google.com", 443);
+    }
+
+    public void testMultipleDomains() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.multiple_domains);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isHstsEnforced());
+        assertFalse(config.getTrustAnchors().isEmpty());
+        PinSet pinSet = config.getPins();
+        assertTrue(pinSet.pins.isEmpty());
+        // Both android.com and google.com should use the same config
+        NetworkSecurityConfig other = appConfig.getConfigForHostname("google.com");
+        assertEquals(config, other);
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "google.com", 443);
+        TestUtils.assertConnectionFails(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testMultipleDomainConfigs() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.multiple_configs);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        // Should be two different config objects
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        NetworkSecurityConfig other = appConfig.getConfigForHostname("google.com");
+        MoreAsserts.assertNotEqual(config, other);
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "google.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testIncludeSubdomains() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.subdomains);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "developer.android.com", 443);
+        TestUtils.assertConnectionFails(context, "google.com", 443);
+    }
+
+    public void testAttributes() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.attributes);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertFalse(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        assertTrue(config.isHstsEnforced());
+        assertFalse(config.isCleartextTrafficPermitted());
+    }
+
+    public void testResourcePemCertificateSource() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.resource_anchors_pem);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        // Check android.com.
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isHstsEnforced());
+        assertEquals(2, config.getTrustAnchors().size());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionFails(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionFails(context, "google.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testResourceDerCertificateSource() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.resource_anchors_der);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        // Check android.com.
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        assertTrue(config.isCleartextTrafficPermitted());
+        assertFalse(config.isHstsEnforced());
+        assertEquals(2, config.getTrustAnchors().size());
+        // Try connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionFails(context, "developer.android.com", 443);
+        TestUtils.assertUrlConnectionFails(context, "google.com", 443);
+        TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
+    }
+
+    public void testNestedDomainConfigs() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.nested_domains);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig parent = appConfig.getConfigForHostname("android.com");
+        NetworkSecurityConfig child = appConfig.getConfigForHostname("developer.android.com");
+        MoreAsserts.assertNotEqual(parent, child);
+        MoreAsserts.assertEmpty(parent.getPins().pins);
+        MoreAsserts.assertNotEmpty(child.getPins().pins);
+        // Check that the child inherited the cleartext value and anchors.
+        assertFalse(child.isCleartextTrafficPermitted());
+        MoreAsserts.assertNotEmpty(child.getTrustAnchors());
+        // Test connections.
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+    }
+
+    public void testNestedDomainConfigsOverride() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.nested_domains_override);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig parent = appConfig.getConfigForHostname("android.com");
+        NetworkSecurityConfig child = appConfig.getConfigForHostname("developer.android.com");
+        MoreAsserts.assertNotEqual(parent, child);
+        assertTrue(parent.isCleartextTrafficPermitted());
+        assertFalse(child.isCleartextTrafficPermitted());
+    }
+
+    public void testDebugOverridesDisabled() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_basic, false);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        Set<TrustAnchor> anchors = config.getTrustAnchors();
+        MoreAsserts.assertEmpty(anchors);
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionFails(context, "android.com", 443);
+        TestUtils.assertConnectionFails(context, "developer.android.com", 443);
+    }
+
+    public void testBasicDebugOverrides() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_basic, true);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        Set<TrustAnchor> anchors = config.getTrustAnchors();
+        MoreAsserts.assertNotEmpty(anchors);
+        for (TrustAnchor anchor : anchors) {
+            assertTrue(anchor.overridesPins);
+        }
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+    }
+
+    public void testDebugOverridesWithDomain() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_domain, true);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        Set<TrustAnchor> anchors = config.getTrustAnchors();
+        boolean foundDebugCA = false;
+        for (TrustAnchor anchor : anchors) {
+            if (anchor.certificate.getSubjectDN().toString().equals(DEBUG_CA_SUBJ)) {
+                foundDebugCA = true;
+                assertTrue(anchor.overridesPins);
+            }
+        }
+        assertTrue(foundDebugCA);
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+    }
+
+    public void testDebugInherit() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_domain, true);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
+        Set<TrustAnchor> anchors = config.getTrustAnchors();
+        boolean foundDebugCA = false;
+        for (TrustAnchor anchor : anchors) {
+            if (anchor.certificate.getSubjectDN().toString().equals(DEBUG_CA_SUBJ)) {
+                foundDebugCA = true;
+                assertTrue(anchor.overridesPins);
+            }
+        }
+        assertTrue(foundDebugCA);
+        assertTrue(anchors.size() > 1);
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+    }
+
+    private void testBadConfig(int configId) throws Exception {
+        try {
+            XmlConfigSource source = new XmlConfigSource(getContext(), configId);
+            ApplicationConfig appConfig = new ApplicationConfig(source);
+            appConfig.getConfigForHostname("android.com");
+            fail("Bad config " + getContext().getResources().getResourceName(configId)
+                    + " did not fail to parse");
+        } catch (RuntimeException e) {
+            MoreAsserts.assertAssignableFrom(XmlConfigSource.ParserException.class,
+                    e.getCause());
+        }
+    }
+
+    public void testBadConfig0() throws Exception {
+        testBadConfig(R.xml.bad_config0);
+    }
+
+    public void testBadConfig1() throws Exception {
+        testBadConfig(R.xml.bad_config1);
+    }
+
+    public void testBadConfig2() throws Exception {
+        testBadConfig(R.xml.bad_config2);
+    }
+
+    public void testBadConfig3() throws Exception {
+        testBadConfig(R.xml.bad_config3);
+    }
+
+    public void testBadConfig4() throws Exception {
+        testBadConfig(R.xml.bad_config4);
+    }
+
+    public void testBadConfig5() throws Exception {
+        testBadConfig(R.xml.bad_config4);
+    }
+
+    public void testTrustManagerKeystore() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.bad_pin, true);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        Provider provider = new NetworkSecurityConfigProvider();
+        TrustManagerFactory tmf =
+                TrustManagerFactory.getInstance("PKIX", provider);
+        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+        keystore.load(null);
+        int i = 0;
+        for (X509Certificate cert : SystemCertificateSource.getInstance().getCertificates()) {
+            keystore.setEntry(String.valueOf(i),
+                    new KeyStore.TrustedCertificateEntry(cert),
+                    null);
+            i++;
+        }
+        tmf.init(keystore);
+        TrustManager[] tms = tmf.getTrustManagers();
+        SSLContext context = SSLContext.getInstance("TLS");
+        context.init(null, tms, null);
+        TestUtils.assertConnectionSucceeds(context, "android.com" , 443);
+    }
+}
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index ceed21e..ec29c38 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -80,6 +80,7 @@
 	util/StringPiece_test.cpp \
 	util/Util_test.cpp \
 	ConfigDescription_test.cpp \
+	java/AnnotationProcessor_test.cpp \
 	java/JavaClassGenerator_test.cpp \
 	java/ManifestClassGenerator_test.cpp \
 	Locale_test.cpp \
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 2d6c0c2..d292f62 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -49,6 +49,13 @@
     return {};
 }
 
+/**
+ * Returns true if the element is <skip> or <eat-comment> and can be safely ignored.
+ */
+static bool shouldIgnoreElement(const StringPiece16& ns, const StringPiece16& name) {
+    return ns.empty() && (name == u"skip" || name == u"eat-comment");
+}
+
 ResourceParser::ResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source,
                                const ConfigDescription& config,
                                const ResourceParserOptions& options) :
@@ -205,16 +212,14 @@
         }
     }
 
-    if (!res->value) {
-        return true;
-    }
+    if (res->value) {
+        // Attach the comment, source and config to the value.
+        res->value->setComment(std::move(res->comment));
+        res->value->setSource(std::move(res->source));
 
-    // Attach the comment, source and config to the value.
-    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)) {
-        return false;
+        if (!table->addResource(res->name, res->id, config, std::move(res->value), diag)) {
+            return false;
+        }
     }
 
     bool error = false;
@@ -259,17 +264,6 @@
             continue;
         }
 
-        Maybe<StringPiece16> maybeName = findNonEmptyAttribute(parser, u"name");
-        if (!maybeName) {
-            mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                         << "<" << elementName << "> tag must have a 'name' attribute");
-            error = true;
-            continue;
-        }
-
-        // Check if we should skip this product.
-        const bool stripResource = shouldStripResource(parser, mOptions.product);
-
         if (elementName == u"item") {
             // Items simply have their type encoded in the type attribute.
             if (Maybe<StringPiece16> maybeType = findNonEmptyAttribute(parser, u"type")) {
@@ -283,10 +277,22 @@
         }
 
         ParsedResource parsedResource;
-        parsedResource.name.entry = maybeName.value().toString();
         parsedResource.source = mSource.withLine(parser->getLineNumber());
         parsedResource.comment = std::move(comment);
 
+        if (Maybe<StringPiece16> maybeName = findNonEmptyAttribute(parser, u"name")) {
+            parsedResource.name.entry = maybeName.value().toString();
+
+        } else if (elementName != u"public-group") {
+            mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
+                         << "<" << elementName << "> tag must have a 'name' attribute");
+            error = true;
+            continue;
+        }
+
+        // Check if we should skip this product.
+        const bool stripResource = shouldStripResource(parser, mOptions.product);
+
         bool result = true;
         if (elementName == u"id") {
             parsedResource.name.type = ResourceType::kId;
@@ -337,9 +343,24 @@
             result = parsePublic(parser, &parsedResource);
         } else if (elementName == u"java-symbol" || elementName == u"symbol") {
             result = parseSymbol(parser, &parsedResource);
+        } else if (elementName == u"public-group") {
+            result = parsePublicGroup(parser, &parsedResource);
         } else {
-            mDiag->warn(DiagMessage(mSource.withLine(parser->getLineNumber()))
-                        << "unknown resource type '" << elementName << "'");
+            // Try parsing the elementName (or type) as a resource. These shall only be
+            // resources like 'layout' or 'xml' and they can only be references.
+            if (const ResourceType* type = parseResourceType(elementName)) {
+                parsedResource.name.type = *type;
+                parsedResource.value = parseXml(parser, android::ResTable_map::TYPE_REFERENCE,
+                                                false);
+                if (!parsedResource.value) {
+                    mDiag->error(DiagMessage(parsedResource.source) << "invalid value for type '"
+                                 << *type << "'. Expected a reference");
+                    result = false;
+                }
+            } else {
+                mDiag->warn(DiagMessage(mSource.withLine(parser->getLineNumber()))
+                            << "unknown resource type '" << elementName << "'");
+            }
         }
 
         if (result) {
@@ -446,11 +467,11 @@
         }
     }
 
-    bool untranslateable = false;
-    if (Maybe<StringPiece16> untranslateableAttr = findAttribute(parser, u"untranslateable")) {
-        if (!ResourceUtils::tryParseBool(untranslateableAttr.value(), &untranslateable)) {
+    bool translateable = mOptions.translatable;
+    if (Maybe<StringPiece16> translateableAttr = findAttribute(parser, u"translatable")) {
+        if (!ResourceUtils::tryParseBool(translateableAttr.value(), &translateable)) {
             mDiag->error(DiagMessage(source)
-                         << "invalid value for 'untranslateable'. Must be a boolean");
+                         << "invalid value for 'translatable'. Must be a boolean");
             return false;
         }
     }
@@ -461,10 +482,10 @@
         return false;
     }
 
-    if (formatted || untranslateable) {
+    if (formatted && translateable) {
         if (String* stringValue = valueCast<String>(outResource->value.get())) {
             if (!util::verifyJavaStringFormat(*stringValue->value)) {
-                mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber()))
+                mDiag->error(DiagMessage(source)
                              << "multiple substitutions specified in non-positional format; "
                                 "did you mean to add the formatted=\"false\" attribute?");
                 return false;
@@ -559,6 +580,92 @@
     return true;
 }
 
+bool ResourceParser::parsePublicGroup(XmlPullParser* parser, ParsedResource* outResource) {
+    const Source source = mSource.withLine(parser->getLineNumber());
+
+    Maybe<StringPiece16> maybeType = findNonEmptyAttribute(parser, u"type");
+    if (!maybeType) {
+        mDiag->error(DiagMessage(source) << "<public-group> must have a 'type' attribute");
+        return false;
+    }
+
+    const ResourceType* parsedType = parseResourceType(maybeType.value());
+    if (!parsedType) {
+        mDiag->error(DiagMessage(source) << "invalid resource type '" << maybeType.value()
+                     << "' in <public-group>");
+        return false;
+    }
+
+    Maybe<StringPiece16> maybeId = findNonEmptyAttribute(parser, u"first-id");
+    if (!maybeId) {
+        mDiag->error(DiagMessage(source) << "<public-group> must have a 'first-id' attribute");
+        return false;
+    }
+
+    android::Res_value val;
+    bool result = android::ResTable::stringToInt(maybeId.value().data(),
+                                                 maybeId.value().size(), &val);
+    ResourceId nextId(val.data);
+    if (!result || !nextId.isValid()) {
+        mDiag->error(DiagMessage(source) << "invalid resource ID '" << maybeId.value()
+                     << "' in <public-group>");
+        return false;
+    }
+
+    std::u16string comment;
+    bool error = false;
+    const size_t depth = parser->getDepth();
+    while (XmlPullParser::nextChildNode(parser, depth)) {
+        if (parser->getEvent() == XmlPullParser::Event::kComment) {
+            comment = util::trimWhitespace(parser->getComment()).toString();
+            continue;
+        } else if (parser->getEvent() != XmlPullParser::Event::kStartElement) {
+            // Skip text.
+            continue;
+        }
+
+        const Source itemSource = mSource.withLine(parser->getLineNumber());
+        const std::u16string& elementNamespace = parser->getElementNamespace();
+        const std::u16string& elementName = parser->getElementName();
+        if (elementNamespace.empty() && elementName == u"public") {
+            Maybe<StringPiece16> maybeName = findNonEmptyAttribute(parser, u"name");
+            if (!maybeName) {
+                mDiag->error(DiagMessage(itemSource) << "<public> must have a 'name' attribute");
+                error = true;
+                continue;
+            }
+
+            if (findNonEmptyAttribute(parser, u"id")) {
+                mDiag->error(DiagMessage(itemSource) << "'id' is ignored within <public-group>");
+                error = true;
+                continue;
+            }
+
+            if (findNonEmptyAttribute(parser, u"type")) {
+                mDiag->error(DiagMessage(itemSource) << "'type' is ignored within <public-group>");
+                error = true;
+                continue;
+            }
+
+            ParsedResource childResource;
+            childResource.name.type = *parsedType;
+            childResource.name.entry = maybeName.value().toString();
+            childResource.id = nextId;
+            childResource.comment = std::move(comment);
+            childResource.source = itemSource;
+            childResource.symbolState = SymbolState::kPublic;
+            outResource->childResources.push_back(std::move(childResource));
+
+            nextId.id += 1;
+
+        } else if (!shouldIgnoreElement(elementNamespace, elementName)) {
+            mDiag->error(DiagMessage(itemSource) << ":" << elementName << ">");
+            error = true;
+        }
+    }
+    return !error;
+}
+
 bool ResourceParser::parseSymbol(XmlPullParser* parser, ParsedResource* outResource) {
     const Source source = mSource.withLine(parser->getLineNumber());
 
@@ -608,12 +715,7 @@
     return mask;
 }
 
-/**
- * Returns true if the element is <skip> or <eat-comment> and can be safely ignored.
- */
-static bool shouldIgnoreElement(const StringPiece16& ns, const StringPiece16& name) {
-    return ns.empty() && (name == u"skip" || name == u"eat-comment");
-}
+
 
 bool ResourceParser::parseAttr(XmlPullParser* parser, ParsedResource* outResource) {
     outResource->source = mSource.withLine(parser->getLineNumber());
@@ -645,7 +747,13 @@
         }
     }
 
-    std::vector<Attribute::Symbol> items;
+    struct SymbolComparator {
+        bool operator()(const Attribute::Symbol& a, const Attribute::Symbol& b) {
+            return a.symbol.name.value() < b.symbol.name.value();
+        }
+    };
+
+    std::set<Attribute::Symbol, SymbolComparator> items;
 
     std::u16string comment;
     bool error = false;
@@ -683,15 +791,27 @@
             }
 
             if (Maybe<Attribute::Symbol> s = parseEnumOrFlagItem(parser, elementName)) {
+                Attribute::Symbol& symbol = s.value();
                 ParsedResource childResource;
-                childResource.name = s.value().symbol.name.value();
+                childResource.name = symbol.symbol.name.value();
                 childResource.source = itemSource;
                 childResource.value = util::make_unique<Id>();
                 outResource->childResources.push_back(std::move(childResource));
 
-                s.value().symbol.setComment(std::move(comment));
-                s.value().symbol.setSource(itemSource);
-                items.push_back(std::move(s.value()));
+                symbol.symbol.setComment(std::move(comment));
+                symbol.symbol.setSource(itemSource);
+
+                auto insertResult = items.insert(std::move(symbol));
+                if (!insertResult.second) {
+                    const Attribute::Symbol& existingSymbol = *insertResult.first;
+                    mDiag->error(DiagMessage(itemSource)
+                                 << "duplicate symbol '" << existingSymbol.symbol.name.value().entry
+                                 << "'");
+
+                    mDiag->note(DiagMessage(existingSymbol.symbol.getSource())
+                                << "first defined here");
+                    error = true;
+                }
             } else {
                 error = true;
             }
@@ -708,7 +828,7 @@
     }
 
     std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(weak);
-    attr->symbols.swap(items);
+    attr->symbols = std::vector<Attribute::Symbol>(items.begin(), items.end());
     attr->typeMask = typeMask ? typeMask : uint32_t(android::ResTable_map::TYPE_ANY);
     outResource->value = std::move(attr);
     return true;
@@ -973,6 +1093,9 @@
     const Source source = mSource.withLine(parser->getLineNumber());
     std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
 
+    // Declare-styleable is kPrivate by default, because it technically only exists in R.java.
+    outResource->symbolState = SymbolState::kPublic;
+
     std::u16string comment;
     bool error = false;
     const size_t depth = parser->getDepth();
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 2d5a29d..18101ee 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -40,6 +40,11 @@
      * that don't match before we compile them.
      */
     Maybe<std::u16string> product;
+
+    /**
+     * Whether the default setting for this parser is to allow translation.
+     */
+    bool translatable = true;
 };
 
 /*
@@ -78,6 +83,7 @@
     bool parseColor(XmlPullParser* parser, ParsedResource* outResource);
     bool parsePrimitive(XmlPullParser* parser, ParsedResource* outResource);
     bool parsePublic(XmlPullParser* parser, ParsedResource* outResource);
+    bool parsePublicGroup(XmlPullParser* parser, ParsedResource* outResource);
     bool parseSymbol(XmlPullParser* parser, ParsedResource* outResource);
     bool parseAttr(XmlPullParser* parser, ParsedResource* outResource);
     bool parseAttrImpl(XmlPullParser* parser, ParsedResource* outResource, bool weak);
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 2f5daae..b59eb95 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -52,8 +52,10 @@
                                          Maybe<std::u16string> product = {}) {
         std::stringstream input(kXmlPreamble);
         input << "<resources>\n" << str << "\n</resources>" << std::endl;
+        ResourceParserOptions parserOptions;
+        parserOptions.product = product;
         ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{ "test" }, {},
-                              ResourceParserOptions{ product });
+                              parserOptions);
         XmlPullParser xmlParser(input);
         if (parser.parse(&xmlParser)) {
             return ::testing::AssertionSuccess();
@@ -80,6 +82,14 @@
     EXPECT_EQ(std::u16string(u"?123"), *str->value);
 }
 
+TEST_F(ResourceParserTest, ParseFormattedString) {
+    std::string input = "<string name=\"foo\">%d %s</string>";
+    ASSERT_FALSE(testParse(input));
+
+    input = "<string name=\"foo\">%1$d %2$s</string>";
+    ASSERT_TRUE(testParse(input));
+}
+
 TEST_F(ResourceParserTest, IgnoreXliffTags) {
     std::string input = "<string name=\"foo\" \n"
                         "        xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n"
@@ -322,6 +332,11 @@
                         "</declare-styleable>";
     ASSERT_TRUE(testParse(input));
 
+    Maybe<ResourceTable::SearchResult> result =
+            mTable.findResource(test::parseNameOrDie(u"@styleable/foo"));
+    AAPT_ASSERT_TRUE(result);
+    EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state);
+
     Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/bar");
     ASSERT_NE(attr, nullptr);
     EXPECT_TRUE(attr->isWeak());
@@ -474,4 +489,44 @@
     ASSERT_FALSE(testParse(input, std::u16string(u"phone")));
 }
 
+TEST_F(ResourceParserTest, AutoIncrementIdsInPublicGroup) {
+    std::string input = R"EOF(
+    <public-group type="attr" first-id="0x01010040">
+      <public name="foo" />
+      <public name="bar" />
+    </public-group>)EOF";
+    ASSERT_TRUE(testParse(input));
+
+    Maybe<ResourceTable::SearchResult> result = mTable.findResource(
+            test::parseNameOrDie(u"@attr/foo"));
+    AAPT_ASSERT_TRUE(result);
+
+    AAPT_ASSERT_TRUE(result.value().package->id);
+    AAPT_ASSERT_TRUE(result.value().type->id);
+    AAPT_ASSERT_TRUE(result.value().entry->id);
+    ResourceId actualId(result.value().package->id.value(),
+                        result.value().type->id.value(),
+                        result.value().entry->id.value());
+    EXPECT_EQ(ResourceId(0x01010040), actualId);
+
+    result = mTable.findResource(test::parseNameOrDie(u"@attr/bar"));
+    AAPT_ASSERT_TRUE(result);
+
+    AAPT_ASSERT_TRUE(result.value().package->id);
+    AAPT_ASSERT_TRUE(result.value().type->id);
+    AAPT_ASSERT_TRUE(result.value().entry->id);
+    actualId = ResourceId(result.value().package->id.value(),
+                          result.value().type->id.value(),
+                          result.value().entry->id.value());
+    EXPECT_EQ(ResourceId(0x01010041), actualId);
+}
+
+TEST_F(ResourceParserTest, ExternalTypesShouldOnlyBeReferences) {
+    std::string input = R"EOF(<item type="layout" name="foo">@layout/bar</item>)EOF";
+    ASSERT_TRUE(testParse(input));
+
+    input = R"EOF(<item type="layout" name="bar">"this is a string"</item>)EOF";
+    ASSERT_FALSE(testParse(input));
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index fa4b109..73d8585 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -190,22 +190,32 @@
 
 bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config,
                                 std::unique_ptr<Value> value, IDiagnostics* diag) {
-    return addResourceImpl(name, {}, config, std::move(value), kValidNameChars, diag);
+    return addResourceImpl(name, {}, config, std::move(value), kValidNameChars,
+                           resolveValueCollision, diag);
 }
 
 bool ResourceTable::addResource(const ResourceNameRef& name, const ResourceId resId,
                                 const ConfigDescription& config, std::unique_ptr<Value> value,
                                 IDiagnostics* diag) {
-    return addResourceImpl(name, resId, config, std::move(value), kValidNameChars, diag);
+    return addResourceImpl(name, resId, config, std::move(value), kValidNameChars,
+                           resolveValueCollision, diag);
 }
 
 bool ResourceTable::addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
                                      const Source& source, const StringPiece16& path,
                                      IDiagnostics* diag) {
+    return addFileReference(name, config, source, path, resolveValueCollision, diag);
+}
+
+bool ResourceTable::addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
+                                     const Source& source, const StringPiece16& path,
+                                     std::function<int(Value*,Value*)> conflictResolver,
+                                     IDiagnostics* diag) {
     std::unique_ptr<FileReference> fileRef = util::make_unique<FileReference>(
             stringPool.makeRef(path));
     fileRef->setSource(source);
-    return addResourceImpl(name, ResourceId{}, config, std::move(fileRef), kValidNameChars, diag);
+    return addResourceImpl(name, ResourceId{}, config, std::move(fileRef), kValidNameChars,
+                           conflictResolver, diag);
 }
 
 bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
@@ -213,7 +223,7 @@
                                             std::unique_ptr<Value> value,
                                             IDiagnostics* diag) {
     return addResourceImpl(name, ResourceId{}, config, std::move(value), kValidNameMangledChars,
-                           diag);
+                           resolveValueCollision, diag);
 }
 
 bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
@@ -221,12 +231,17 @@
                                             const ConfigDescription& config,
                                             std::unique_ptr<Value> value,
                                             IDiagnostics* diag) {
-    return addResourceImpl(name, id, config, std::move(value), kValidNameMangledChars, diag);
+    return addResourceImpl(name, id, config, std::move(value), kValidNameMangledChars,
+                           resolveValueCollision, diag);
 }
 
-bool ResourceTable::addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
-                                    const ConfigDescription& config, std::unique_ptr<Value> value,
-                                    const char16_t* validChars, IDiagnostics* diag) {
+bool ResourceTable::addResourceImpl(const ResourceNameRef& name,
+                                    const ResourceId resId,
+                                    const ConfigDescription& config,
+                                    std::unique_ptr<Value> value,
+                                    const char16_t* validChars,
+                                    std::function<int(Value*,Value*)> conflictResolver,
+                                    IDiagnostics* diag) {
     assert(value && "value can't be nullptr");
     assert(diag && "diagnostics can't be nullptr");
 
@@ -284,12 +299,12 @@
     }
 
     const auto endIter = entry->values.end();
-    auto iter = std::lower_bound(entry->values.begin(), endIter, config, cmp::lessThan);
+    auto iter = std::lower_bound(entry->values.begin(), endIter, config, cmp::lessThanConfig);
     if (iter == endIter || iter->config != config) {
         // This resource did not exist before, add it.
         entry->values.insert(iter, ResourceConfigValue{ config, std::move(value) });
     } else {
-        int collisionResult = resolveValueCollision(iter->value.get(), value.get());
+        int collisionResult = conflictResolver(iter->value.get(), value.get());
         if (collisionResult > 0) {
             // Take the incoming value.
             iter->value = std::move(value);
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 980504b..6b7b07e 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -163,7 +163,12 @@
                      IDiagnostics* diag);
 
     bool addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
-                          const Source& source, const StringPiece16& path, IDiagnostics* diag);
+                          const Source& source, const StringPiece16& path,
+                          IDiagnostics* diag);
+
+    bool addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
+                          const Source& source, const StringPiece16& path,
+                          std::function<int(Value*,Value*)> conflictResolver, IDiagnostics* diag);
 
     /**
      * Same as addResource, but doesn't verify the validity of the name. This is used
@@ -221,9 +226,14 @@
 private:
     ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
 
-    bool addResourceImpl(const ResourceNameRef& name, ResourceId resId,
-                         const ConfigDescription& config, std::unique_ptr<Value> value,
-                         const char16_t* validChars, IDiagnostics* diag);
+    bool addResourceImpl(const ResourceNameRef& name,
+                         ResourceId resId,
+                         const ConfigDescription& config,
+                         std::unique_ptr<Value> value,
+                         const char16_t* validChars,
+                         std::function<int(Value*,Value*)> conflictResolver,
+                         IDiagnostics* diag);
+
     bool setSymbolStateImpl(const ResourceNameRef& name, ResourceId resId,
                             const Symbol& symbol, const char16_t* validChars, IDiagnostics* diag);
 };
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index d3c3c10..b1a4c7d 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -23,22 +23,28 @@
 namespace aapt {
 namespace ResourceUtils {
 
-void extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
+bool extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
                          StringPiece16* outType, StringPiece16* outEntry) {
+    bool hasPackageSeparator = false;
+    bool hasTypeSeparator = false;
     const char16_t* start = str.data();
     const char16_t* end = start + str.size();
     const char16_t* current = start;
     while (current != end) {
         if (outType->size() == 0 && *current == u'/') {
+            hasTypeSeparator = true;
             outType->assign(start, current - start);
             start = current + 1;
         } else if (outPackage->size() == 0 && *current == u':') {
+            hasPackageSeparator = true;
             outPackage->assign(start, current - start);
             start = current + 1;
         }
         current++;
     }
     outEntry->assign(start, end - start);
+
+    return !(hasPackageSeparator && outPackage->empty()) && !(hasTypeSeparator && outType->empty());
 }
 
 bool tryParseReference(const StringPiece16& str, ResourceNameRef* outRef, bool* outCreate,
@@ -62,26 +68,34 @@
         StringPiece16 package;
         StringPiece16 type;
         StringPiece16 entry;
-        extractResourceName(trimmedStr.substr(offset, trimmedStr.size() - offset), &package, &type,
-                            &entry);
+        if (!extractResourceName(trimmedStr.substr(offset, trimmedStr.size() - offset),
+                                 &package, &type, &entry)) {
+            return false;
+        }
 
         const ResourceType* parsedType = parseResourceType(type);
         if (!parsedType) {
             return false;
         }
 
+        if (entry.empty()) {
+            return false;
+        }
+
         if (create && *parsedType != ResourceType::kId) {
             return false;
         }
 
-        if (outRef != nullptr) {
+        if (outRef) {
             outRef->package = package;
             outRef->type = *parsedType;
             outRef->entry = entry;
         }
+
         if (outCreate) {
             *outCreate = create;
         }
+
         if (outPrivate) {
             *outPrivate = priv;
         }
@@ -104,20 +118,33 @@
         StringPiece16 package;
         StringPiece16 type;
         StringPiece16 entry;
-        extractResourceName(trimmedStr.substr(1, trimmedStr.size() - 1), &package, &type, &entry);
+        if (!extractResourceName(trimmedStr.substr(1, trimmedStr.size() - 1),
+                                 &package, &type, &entry)) {
+            return false;
+        }
 
         if (!type.empty() && type != u"attr") {
             return false;
         }
 
-        outRef->package = package;
-        outRef->type = ResourceType::kAttr;
-        outRef->entry = entry;
+        if (entry.empty()) {
+            return false;
+        }
+
+        if (outRef) {
+            outRef->package = package;
+            outRef->type = ResourceType::kAttr;
+            outRef->entry = entry;
+        }
         return true;
     }
     return false;
 }
 
+bool isAttributeReference(const StringPiece16& str) {
+    return tryParseAttributeReference(str, nullptr);
+}
+
 /*
  * Style parent's are a bit different. We accept the following formats:
  *
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index 851edc8..34daa66 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -34,8 +34,9 @@
  *
  * where the package can be empty. Validation must be performed on each
  * individual extracted piece to verify that the pieces are valid.
+ * Returns false if there was no package but a ':' was present.
  */
-void extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
+bool extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
                          StringPiece16* outType, StringPiece16* outEntry);
 
 /*
@@ -54,12 +55,17 @@
 bool isReference(const StringPiece16& str);
 
 /*
- * Returns true if the string was parsed as an attribute reference (?[package:]type/name),
+ * Returns true if the string was parsed as an attribute reference (?[package:][type/]name),
  * with `outReference` set to the parsed reference.
  */
 bool tryParseAttributeReference(const StringPiece16& str, ResourceNameRef* outReference);
 
 /**
+ * Returns true if the string is in the form of an attribute reference(?[package:][type/]name).
+ */
+bool isAttributeReference(const StringPiece16& str);
+
+/**
  * Returns true if the value is a boolean, putting the result in `outValue`.
  */
 bool tryParseBool(const StringPiece16& str, bool* outValue);
diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp
index 7de8f41..3d2a6e1 100644
--- a/tools/aapt2/ResourceUtils_test.cpp
+++ b/tools/aapt2/ResourceUtils_test.cpp
@@ -90,6 +90,26 @@
                                                   &privateRef));
 }
 
+TEST(ResourceUtilsTest, ParseAttributeReferences) {
+    EXPECT_TRUE(ResourceUtils::isAttributeReference(u"?android"));
+    EXPECT_TRUE(ResourceUtils::isAttributeReference(u"?android:foo"));
+    EXPECT_TRUE(ResourceUtils::isAttributeReference(u"?attr/foo"));
+    EXPECT_TRUE(ResourceUtils::isAttributeReference(u"?android:attr/foo"));
+}
+
+TEST(ResourceUtilsTest, FailParseIncompleteReference) {
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?style/foo"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?android:style/foo"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?android:"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?android:attr/"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?:attr/"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?:attr/foo"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?:/"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?:/foo"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?attr/"));
+    EXPECT_FALSE(ResourceUtils::isAttributeReference(u"?/foo"));
+}
+
 TEST(ResourceUtilsTest, ParseStyleParentReference) {
     const ResourceName kAndroidStyleFooName = { u"android", ResourceType::kStyle, u"foo" };
     const ResourceName kStyleFooName = { {}, ResourceType::kStyle, u"foo" };
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index f312d75..8acff0d 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -44,7 +44,10 @@
 }
 
 RawString* RawString::clone(StringPool* newPool) const {
-    return new RawString(newPool->makeRef(*value));
+    RawString* rs = new RawString(newPool->makeRef(*value));
+    rs->mComment = mComment;
+    rs->mSource = mSource;
+    return rs;
 }
 
 bool RawString::flatten(android::Res_value* outValue) const {
@@ -77,6 +80,8 @@
 
 Reference* Reference::clone(StringPool* /*newPool*/) const {
     Reference* ref = new Reference();
+    ref->mComment = mComment;
+    ref->mSource = mSource;
     ref->referenceType = referenceType;
     ref->name = name;
     ref->id = id;
@@ -111,7 +116,10 @@
 }
 
 Id* Id::clone(StringPool* /*newPool*/) const {
-    return new Id();
+    Id* id = new Id();
+    id->mComment = mComment;
+    id->mSource = mSource;
+    return id;
 }
 
 void Id::print(std::ostream* out) const {
@@ -133,7 +141,10 @@
 }
 
 String* String::clone(StringPool* newPool) const {
-    return new String(newPool->makeRef(*value));
+    String* str = new String(newPool->makeRef(*value));
+    str->mComment = mComment;
+    str->mSource = mSource;
+    return str;
 }
 
 void String::print(std::ostream* out) const {
@@ -154,7 +165,10 @@
 }
 
 StyledString* StyledString::clone(StringPool* newPool) const {
-    return new StyledString(newPool->makeRef(value));
+    StyledString* str = new StyledString(newPool->makeRef(value));
+    str->mComment = mComment;
+    str->mSource = mSource;
+    return str;
 }
 
 void StyledString::print(std::ostream* out) const {
@@ -175,7 +189,10 @@
 }
 
 FileReference* FileReference::clone(StringPool* newPool) const {
-    return new FileReference(newPool->makeRef(*path));
+    FileReference* fr = new FileReference(newPool->makeRef(*path));
+    fr->mComment = mComment;
+    fr->mSource = mSource;
+    return fr;
 }
 
 void FileReference::print(std::ostream* out) const {
@@ -197,7 +214,10 @@
 }
 
 BinaryPrimitive* BinaryPrimitive::clone(StringPool* /*newPool*/) const {
-    return new BinaryPrimitive(value);
+    BinaryPrimitive* bp = new BinaryPrimitive(value);
+    bp->mComment = mComment;
+    bp->mSource = mSource;
+    return bp;
 }
 
 void BinaryPrimitive::print(std::ostream* out) const {
@@ -236,6 +256,8 @@
 
 Attribute* Attribute::clone(StringPool* /*newPool*/) const {
     Attribute* attr = new Attribute(weak);
+    attr->mComment = mComment;
+    attr->mSource = mSource;
     attr->typeMask = typeMask;
     std::copy(symbols.begin(), symbols.end(), std::back_inserter(attr->symbols));
     return attr;
@@ -358,6 +380,8 @@
     Style* style = new Style();
     style->parent = parent;
     style->parentInferred = parentInferred;
+    style->mComment = mComment;
+    style->mSource = mSource;
     for (auto& entry : entries) {
         style->entries.push_back(Entry{
                 entry.key,
@@ -390,6 +414,8 @@
 
 Array* Array::clone(StringPool* newPool) const {
     Array* array = new Array();
+    array->mComment = mComment;
+    array->mSource = mSource;
     for (auto& item : items) {
         array->items.emplace_back(std::unique_ptr<Item>(item->clone(newPool)));
     }
@@ -404,6 +430,8 @@
 
 Plural* Plural::clone(StringPool* newPool) const {
     Plural* p = new Plural();
+    p->mComment = mComment;
+    p->mSource = mSource;
     const size_t count = values.size();
     for (size_t i = 0; i < count; i++) {
         if (values[i]) {
@@ -423,6 +451,8 @@
 
 Styleable* Styleable::clone(StringPool* /*newPool*/) const {
     Styleable* styleable = new Styleable();
+    styleable->mComment = mComment;
+    styleable->mSource = mSource;
     std::copy(entries.begin(), entries.end(), std::back_inserter(styleable->entries));
     return styleable;
 }
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index 2629153..7ae346a 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -91,7 +91,7 @@
      */
     virtual void print(std::ostream* out) const = 0;
 
-private:
+protected:
     Source mSource;
     std::u16string mComment;
 };
diff --git a/tools/aapt2/XmlDom.h b/tools/aapt2/XmlDom.h
index 9a46bcb..721bf5b 100644
--- a/tools/aapt2/XmlDom.h
+++ b/tools/aapt2/XmlDom.h
@@ -215,10 +215,13 @@
         for (auto iter = mPackageDecls.rbegin(); iter != rend; ++iter) {
             if (name.package == iter->prefix) {
                 if (iter->package.empty()) {
-                    return ResourceName{ localPackage.toString(), name.type, name.entry };
-                } else {
+                    if (localPackage != name.package) {
+                        return ResourceName{ localPackage.toString(), name.type, name.entry };
+                    }
+                } else if (iter->package != name.package) {
                     return ResourceName{ iter->package, name.type, name.entry };
                 }
+                break;
             }
         }
         return {};
diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp
index 0bc5dce..39088bc 100644
--- a/tools/aapt2/compile/Compile.cpp
+++ b/tools/aapt2/compile/Compile.cpp
@@ -132,8 +132,15 @@
 
         // Parse the values file from XML.
         XmlPullParser xmlParser(fin);
+
+        ResourceParserOptions parserOptions;
+        parserOptions.product = options.product;
+
+        // If the filename includes donottranslate, then the default translatable is false.
+        parserOptions.translatable = pathData.name.find(u"donottranslate") == std::string::npos;
+
         ResourceParser resParser(context->getDiagnostics(), &table, pathData.source,
-                                 pathData.config, ResourceParserOptions{ options.product });
+                                 pathData.config, parserOptions);
         if (!resParser.parse(&xmlParser)) {
             return false;
         }
@@ -141,10 +148,14 @@
         fin.close();
     }
 
-    ResourceTablePackage* pkg = table.createPackage(context->getCompilationPackage());
-    if (!pkg->id) {
-        // If no package ID was set while parsing (public identifiers), auto assign an ID.
-        pkg->id = context->getPackageId();
+    // Ensure we have the compilation package at least.
+    table.createPackage(context->getCompilationPackage());
+
+    for (auto& pkg : table.packages) {
+        if (!pkg->id) {
+            // If no package ID was set while parsing (public identifiers), auto assign an ID.
+            pkg->id = context->getPackageId();
+        }
     }
 
     // Assign IDs to prepare the table for flattening.
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index b36682d..9c25d4e 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -25,33 +25,20 @@
     static const std::string sDeprecated = "@deprecated";
     static const std::string sSystemApi = "@SystemApi";
 
-    if (comment.find(sDeprecated) != std::string::npos && !mDeprecated) {
-        mDeprecated = true;
-        if (!mAnnotations.empty()) {
-            mAnnotations += "\n";
-        }
-        mAnnotations += mPrefix;
-        mAnnotations += "@Deprecated";
+    if (comment.find(sDeprecated) != std::string::npos) {
+        mAnnotationBitMask |= kDeprecated;
     }
 
-    if (comment.find(sSystemApi) != std::string::npos && !mSystemApi) {
-        mSystemApi = true;
-        if (!mAnnotations.empty()) {
-            mAnnotations += "\n";
-        }
-        mAnnotations += mPrefix;
-        mAnnotations += "@android.annotations.SystemApi";
+    if (comment.find(sSystemApi) != std::string::npos) {
+        mAnnotationBitMask |= kSystemApi;
     }
 
-    if (mComment.empty()) {
-        mComment += mPrefix;
-        mComment += "/**";
+    if (!mHasComments) {
+        mHasComments = true;
+        mComment << "/**";
     }
 
-    mComment += "\n";
-    mComment += mPrefix;
-    mComment += " * ";
-    mComment += std::move(comment);
+    mComment << "\n" << " * " << std::move(comment);
 }
 
 void AnnotationProcessor::appendComment(const StringPiece16& comment) {
@@ -73,17 +60,22 @@
     }
 }
 
-std::string AnnotationProcessor::buildComment() {
-    if (!mComment.empty()) {
-        mComment += "\n";
-        mComment += mPrefix;
-        mComment += " */";
+void AnnotationProcessor::writeToStream(std::ostream* out, const StringPiece& prefix) {
+    if (mHasComments) {
+        std::string result = mComment.str();
+        for (StringPiece line : util::tokenize<char>(result, '\n')) {
+           *out << prefix << line << "\n";
+        }
+        *out << prefix << " */" << "\n";
     }
-    return std::move(mComment);
-}
 
-std::string AnnotationProcessor::buildAnnotations() {
-    return std::move(mAnnotations);
+    if (mAnnotationBitMask & kDeprecated) {
+        *out << prefix << "@Deprecated\n";
+    }
+
+    if (mAnnotationBitMask & kSystemApi) {
+        *out << prefix << "@android.annotation.SystemApi\n";
+    }
 }
 
 } // namespace aapt
diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h
index 81a6f6e..e7f2be0 100644
--- a/tools/aapt2/java/AnnotationProcessor.h
+++ b/tools/aapt2/java/AnnotationProcessor.h
@@ -19,6 +19,7 @@
 
 #include "util/StringPiece.h"
 
+#include <sstream>
 #include <string>
 
 namespace aapt {
@@ -54,13 +55,6 @@
 class AnnotationProcessor {
 public:
     /**
-     * Creates an AnnotationProcessor with a given prefix for each line generated.
-     * This is usually a set of spaces for indentation.
-     */
-    AnnotationProcessor(const StringPiece& prefix) : mPrefix(prefix.toString()) {
-    }
-
-    /**
      * Adds more comments. Since resources can have various values with different configurations,
      * we need to collect all the comments.
      */
@@ -68,23 +62,20 @@
     void appendComment(const StringPiece& comment);
 
     /**
-     * Finishes the comment and moves it to the caller. Subsequent calls to buildComment() have
-     * undefined results.
+     * Writes the comments and annotations to the stream, with the given prefix before each line.
      */
-    std::string buildComment();
-
-    /**
-     * Finishes the annotation and moves it to the caller. Subsequent calls to buildAnnotations()
-     * have undefined results.
-     */
-    std::string buildAnnotations();
+    void writeToStream(std::ostream* out, const StringPiece& prefix);
 
 private:
-    std::string mPrefix;
-    std::string mComment;
-    std::string mAnnotations;
-    bool mDeprecated = false;
-    bool mSystemApi = false;
+    enum : uint32_t {
+        kDeprecated = 0x01,
+        kSystemApi = 0x02,
+    };
+
+    std::stringstream mComment;
+    std::stringstream mAnnotations;
+    bool mHasComments = false;
+    uint32_t mAnnotationBitMask = 0;
 
     void appendCommentLine(const std::string& line);
 };
diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp
new file mode 100644
index 0000000..d5a2b38
--- /dev/null
+++ b/tools/aapt2/java/AnnotationProcessor_test.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ResourceParser.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "XmlPullParser.h"
+
+#include "java/AnnotationProcessor.h"
+
+#include "test/Builders.h"
+#include "test/Context.h"
+
+#include <gtest/gtest.h>
+
+namespace aapt {
+
+struct AnnotationProcessorTest : public ::testing::Test {
+    std::unique_ptr<IAaptContext> mContext;
+    ResourceTable mTable;
+
+    void SetUp() override {
+        mContext = test::ContextBuilder().build();
+    }
+
+    ::testing::AssertionResult parse(const StringPiece& str) {
+        ResourceParserOptions options;
+        ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{}, ConfigDescription{},
+                              options);
+        std::stringstream in;
+        in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str;
+        XmlPullParser xmlParser(in);
+        if (parser.parse(&xmlParser)) {
+            return ::testing::AssertionSuccess();
+        }
+        return ::testing::AssertionFailure();
+    }
+};
+
+TEST_F(AnnotationProcessorTest, EmitsDeprecated) {
+    ASSERT_TRUE(parse(R"EOF(
+    <resources>
+      <declare-styleable name="foo">      
+        <!-- Some comment, and it should contain
+             a marker word, something that marks
+             this resource as nor needed.
+             {@deprecated That's the marker! } -->
+        <attr name="autoText" format="boolean" />
+      </declare-styleable>
+    </resources>)EOF"));
+
+    Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/autoText");
+    ASSERT_NE(nullptr, attr);
+
+    AnnotationProcessor processor;
+    processor.appendComment(attr->getComment());
+
+    std::stringstream result;
+    processor.writeToStream(&result, "");
+    std::string annotations = result.str();
+
+    EXPECT_NE(std::string::npos, annotations.find("@Deprecated"));
+}
+
+} // namespace aapt
+
+
diff --git a/tools/aapt2/java/ClassDefinitionWriter.h b/tools/aapt2/java/ClassDefinitionWriter.h
new file mode 100644
index 0000000..b8886f9
--- /dev/null
+++ b/tools/aapt2/java/ClassDefinitionWriter.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_JAVA_CLASSDEFINITION_H
+#define AAPT_JAVA_CLASSDEFINITION_H
+
+#include "java/AnnotationProcessor.h"
+#include "util/StringPiece.h"
+#include "util/Util.h"
+
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+struct ClassDefinitionWriterOptions {
+    bool useFinalQualifier = false;
+    bool forceCreationIfEmpty = false;
+};
+
+/**
+ * Writes a class for use in R.java or Manifest.java.
+ */
+class ClassDefinitionWriter {
+public:
+    ClassDefinitionWriter(const StringPiece& name, const ClassDefinitionWriterOptions& options) :
+            mName(name.toString()), mOptions(options), mStarted(false) {
+    }
+
+    ClassDefinitionWriter(const StringPiece16& name, const ClassDefinitionWriterOptions& options) :
+            mName(util::utf16ToUtf8(name)), mOptions(options), mStarted(false) {
+    }
+
+    void addIntMember(const StringPiece& name, AnnotationProcessor* processor,
+                      const uint32_t val) {
+        ensureClassDeclaration();
+        if (processor) {
+            processor->writeToStream(&mOut, kIndent);
+        }
+        mOut << kIndent << "public static " << (mOptions.useFinalQualifier ? "final " : "")
+             << "int " << name << "=" << val << ";\n";
+    }
+
+    void addStringMember(const StringPiece16& name, AnnotationProcessor* processor,
+                         const StringPiece16& val) {
+        ensureClassDeclaration();
+        if (processor) {
+            processor->writeToStream(&mOut, kIndent);
+        }
+        mOut << kIndent << "public static " << (mOptions.useFinalQualifier ? "final " : "")
+             << "String " << name << "=\"" << val << "\";\n";
+    }
+
+    void addResourceMember(const StringPiece16& name, AnnotationProcessor* processor,
+                           const ResourceId id) {
+        ensureClassDeclaration();
+        if (processor) {
+            processor->writeToStream(&mOut, kIndent);
+        }
+        mOut << kIndent << "public static " << (mOptions.useFinalQualifier ? "final " : "")
+             << "int " << name << "=" << id <<";\n";
+    }
+
+    template <typename Iterator, typename FieldAccessorFunc>
+    void addArrayMember(const StringPiece16& name, AnnotationProcessor* processor,
+                        const Iterator begin, const Iterator end, FieldAccessorFunc f) {
+        ensureClassDeclaration();
+        if (processor) {
+            processor->writeToStream(&mOut, kIndent);
+        }
+        mOut << kIndent << "public static final int[] " << name << "={";
+
+        for (Iterator current = begin; current != end; ++current) {
+            if (std::distance(begin, current) % kAttribsPerLine == 0) {
+                mOut << "\n" << kIndent << kIndent;
+            }
+
+            mOut << f(*current);
+            if (std::distance(current, end) > 1) {
+                mOut << ", ";
+            }
+        }
+        mOut << "\n" << kIndent <<"};\n";
+    }
+
+    void writeToStream(std::ostream* out, const StringPiece& prefix,
+                       AnnotationProcessor* processor=nullptr) {
+        if (mOptions.forceCreationIfEmpty) {
+            ensureClassDeclaration();
+        }
+
+        if (!mStarted) {
+            return;
+        }
+
+        if (processor) {
+            processor->writeToStream(out, prefix);
+        }
+
+        std::string result = mOut.str();
+        for (StringPiece line : util::tokenize<char>(result, '\n')) {
+            *out << prefix << line << "\n";
+        }
+        *out << prefix << "}\n";
+    }
+
+private:
+    constexpr static const char* kIndent = "  ";
+
+    // The number of attributes to emit per line in a Styleable array.
+    constexpr static size_t kAttribsPerLine = 4;
+
+    void ensureClassDeclaration() {
+        if (!mStarted) {
+            mStarted = true;
+            mOut << "public static final class " << mName << " {\n";
+        }
+    }
+
+    std::stringstream mOut;
+    std::string mName;
+    ClassDefinitionWriterOptions mOptions;
+    bool mStarted;
+};
+
+} // namespace aapt
+
+#endif /* AAPT_JAVA_CLASSDEFINITION_H */
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index dfd2ef6..7280f3a 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -21,7 +21,9 @@
 #include "ValueVisitor.h"
 
 #include "java/AnnotationProcessor.h"
+#include "java/ClassDefinitionWriter.h"
 #include "java/JavaClassGenerator.h"
+#include "util/Comparators.h"
 #include "util/StringPiece.h"
 
 #include <algorithm>
@@ -32,9 +34,6 @@
 
 namespace aapt {
 
-// The number of attributes to emit per line in a Styleable array.
-constexpr size_t kAttribsPerLine = 4;
-
 JavaClassGenerator::JavaClassGenerator(ResourceTable* table, JavaClassGeneratorOptions options) :
         mTable(table), mOptions(options) {
 }
@@ -92,12 +91,11 @@
     return true;
 }
 
-void JavaClassGenerator::generateStyleable(const StringPiece16& packageNameToGenerate,
-                                           const std::u16string& entryName,
-                                           const Styleable* styleable,
-                                           std::ostream* out) {
-    const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
-
+void JavaClassGenerator::writeStyleableEntryForClass(ClassDefinitionWriter* outClassDef,
+                                                     AnnotationProcessor* processor,
+                                                     const StringPiece16& packageNameToGenerate,
+                                                     const std::u16string& entryName,
+                                                     const Styleable* styleable) {
     // This must be sorted by resource ID.
     std::vector<std::pair<ResourceId, ResourceNameRef>> sortedAttributes;
     sortedAttributes.reserve(styleable->entries.size());
@@ -110,36 +108,31 @@
     }
     std::sort(sortedAttributes.begin(), sortedAttributes.end());
 
+    auto accessorFunc = [](const std::pair<ResourceId, ResourceNameRef>& a) -> ResourceId {
+        return a.first;
+    };
+
     // First we emit the array containing the IDs of each attribute.
-    *out << "    "
-         << "public static final int[] " << transform(entryName) << " = {";
-
-    const size_t attrCount = sortedAttributes.size();
-    for (size_t i = 0; i < attrCount; i++) {
-        if (i % kAttribsPerLine == 0) {
-            *out << "\n      ";
-        }
-
-        *out << sortedAttributes[i].first;
-        if (i != attrCount - 1) {
-            *out << ", ";
-        }
-    }
-    *out << "\n    };\n";
+    outClassDef->addArrayMember(transform(entryName), processor,
+                                sortedAttributes.begin(),
+                                sortedAttributes.end(),
+                                accessorFunc);
 
     // Now we emit the indices into the array.
+    size_t attrCount = sortedAttributes.size();
     for (size_t i = 0; i < attrCount; i++) {
-        *out << "    "
-             << "public static" << finalModifier
-             << " int " << transform(entryName);
+        std::stringstream name;
+        name << transform(entryName);
 
         // We may reference IDs from other packages, so prefix the entry name with
         // the package.
         const ResourceNameRef& itemName = sortedAttributes[i].second;
         if (!itemName.package.empty() && packageNameToGenerate != itemName.package) {
-            *out << "_" << transform(itemName.package);
+            name << "_" << transform(itemName.package);
         }
-        *out << "_" << transform(itemName.entry) << " = " << i << ";\n";
+        name << "_" << transform(itemName.entry);
+
+        outClassDef->addIntMember(name.str(), nullptr, i);
     }
 }
 
@@ -155,8 +148,8 @@
 
     if (typeMask & android::ResTable_map::TYPE_STRING) {
         processor->appendComment(
-                "<p>May be a string value, using '\\;' to escape characters such as\n"
-                "'\\n' or '\\uxxxx' for a unicode character;");
+                "<p>May be a string value, using '\\\\;' to escape characters such as\n"
+                "'\\\\n' or '\\\\uxxxx' for a unicode character;");
     }
 
     if (typeMask & android::ResTable_map::TYPE_INTEGER) {
@@ -222,14 +215,10 @@
     }
 }
 
-bool JavaClassGenerator::generateType(const StringPiece16& packageNameToGenerate,
-                                      const ResourceTablePackage* package,
-                                      const ResourceTableType* type,
-                                      std::ostream* out) {
-    const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
-
-    std::u16string unmangledPackage;
-    std::u16string unmangledName;
+bool JavaClassGenerator::writeEntriesForClass(ClassDefinitionWriter* outClassDef,
+                                              const StringPiece16& packageNameToGenerate,
+                                              const ResourceTablePackage* package,
+                                              const ResourceTableType* type) {
     for (const auto& entry : type->entries) {
         if (skipSymbol(entry->symbolStatus.state)) {
             continue;
@@ -238,7 +227,8 @@
         ResourceId id(package->id.value(), type->id.value(), entry->id.value());
         assert(id.isValid());
 
-        unmangledName = entry->name;
+        std::u16string unmangledPackage;
+        std::u16string unmangledName = entry->name;
         if (NameMangler::unmangle(&unmangledName, &unmangledPackage)) {
             // The entry name was mangled, and we successfully unmangled it.
             // Check that we want to emit this symbol.
@@ -246,12 +236,10 @@
                 // Skip the entry if it doesn't belong to the package we're writing.
                 continue;
             }
-        } else {
-            if (packageNameToGenerate != package->name) {
-                // We are processing a mangled package name,
-                // but this is a non-mangled resource.
-                continue;
-            }
+        } else if (packageNameToGenerate != package->name) {
+            // We are processing a mangled package name,
+            // but this is a non-mangled resource.
+            continue;
         }
 
         if (!isValidSymbol(unmangledName)) {
@@ -262,39 +250,33 @@
             return false;
         }
 
+        // Build the comments and annotations for this entry.
+
+        AnnotationProcessor processor;
+        if (entry->symbolStatus.state != SymbolState::kUndefined) {
+            processor.appendComment(entry->symbolStatus.comment);
+        }
+
+        for (const auto& configValue : entry->values) {
+            processor.appendComment(configValue.value->getComment());
+        }
+
+        // If this is an Attribute, append the format Javadoc.
+        if (!entry->values.empty()) {
+            if (Attribute* attr = valueCast<Attribute>(entry->values.front().value.get())) {
+                // We list out the available values for the given attribute.
+                addAttributeFormatDoc(&processor, attr);
+            }
+        }
+
         if (type->type == ResourceType::kStyleable) {
             assert(!entry->values.empty());
-            generateStyleable(packageNameToGenerate, unmangledName, static_cast<const Styleable*>(
-                    entry->values.front().value.get()), out);
+            const Styleable* styleable = static_cast<const Styleable*>(
+                    entry->values.front().value.get());
+            writeStyleableEntryForClass(outClassDef, &processor, packageNameToGenerate,
+                                        unmangledName, styleable);
         } else {
-            AnnotationProcessor processor("    ");
-            if (entry->symbolStatus.state != SymbolState::kUndefined) {
-                processor.appendComment(entry->symbolStatus.comment);
-            }
-
-            for (const auto& configValue : entry->values) {
-                processor.appendComment(configValue.value->getComment());
-            }
-
-            if (!entry->values.empty()) {
-                if (Attribute* attr = valueCast<Attribute>(entry->values.front().value.get())) {
-                    // We list out the available values for the given attribute.
-                    addAttributeFormatDoc(&processor, attr);
-                }
-            }
-
-            std::string comment = processor.buildComment();
-            if (!comment.empty()) {
-                *out << comment << "\n";
-            }
-
-            std::string annotations = processor.buildAnnotations();
-            if (!annotations.empty()) {
-                *out << annotations << "\n";
-            }
-
-            *out << "    " << "public static" << finalModifier
-                 << " int " << transform(unmangledName) << " = " << id << ";\n";
+            outClassDef->addResourceMember(transform(unmangledName), &processor, id);
         }
     }
     return true;
@@ -312,17 +294,42 @@
 
     for (const auto& package : mTable->packages) {
         for (const auto& type : package->types) {
-            StringPiece16 typeStr;
             if (type->type == ResourceType::kAttrPrivate) {
-                typeStr = toString(ResourceType::kAttr);
-            } else {
-                typeStr = toString(type->type);
+                continue;
             }
-            *out << "  public static final class " << typeStr << " {\n";
-            if (!generateType(packageNameToGenerate, package.get(), type.get(), out)) {
+
+            ClassDefinitionWriterOptions classOptions;
+            classOptions.useFinalQualifier = mOptions.useFinal;
+            classOptions.forceCreationIfEmpty =
+                    (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic);
+            ClassDefinitionWriter classDef(toString(type->type), classOptions);
+            bool result = writeEntriesForClass(&classDef, packageNameToGenerate,
+                                               package.get(), type.get());
+            if (!result) {
                 return false;
             }
-            *out << "  }\n";
+
+            if (type->type == ResourceType::kAttr) {
+                // Also include private attributes in this same class.
+                auto iter = std::lower_bound(package->types.begin(), package->types.end(),
+                                             ResourceType::kAttrPrivate, cmp::lessThanType);
+                if (iter != package->types.end() && (*iter)->type == ResourceType::kAttrPrivate) {
+                    result = writeEntriesForClass(&classDef, packageNameToGenerate,
+                                                  package.get(), iter->get());
+                    if (!result) {
+                        return false;
+                    }
+                }
+            }
+
+            AnnotationProcessor processor;
+            if (type->type == ResourceType::kStyleable &&
+                    mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) {
+                // When generating a public R class, we don't want Styleable to be part of the API.
+                // It is only emitted for documentation purposes.
+                processor.appendComment("@doconly");
+            }
+            classDef.writeToStream(out, "  ", &processor);
         }
     }
 
diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h
index e53a765..023d6d6 100644
--- a/tools/aapt2/java/JavaClassGenerator.h
+++ b/tools/aapt2/java/JavaClassGenerator.h
@@ -27,6 +27,9 @@
 
 namespace aapt {
 
+class AnnotationProcessor;
+class ClassDefinitionWriter;
+
 struct JavaClassGeneratorOptions {
     /*
      * Specifies whether to use the 'final' modifier
@@ -40,9 +43,6 @@
         kPublic,
     };
 
-    /*
-     *
-     */
     SymbolTypes types = SymbolTypes::kAll;
 };
 
@@ -69,15 +69,16 @@
     const std::string& getError() const;
 
 private:
-    bool generateType(const StringPiece16& packageNameToGenerate,
-                      const ResourceTablePackage* package,
-                      const ResourceTableType* type,
-                      std::ostream* out);
+    bool writeEntriesForClass(ClassDefinitionWriter* outClassDef,
+                              const StringPiece16& packageNameToGenerate,
+                              const ResourceTablePackage* package,
+                              const ResourceTableType* type);
 
-    void generateStyleable(const StringPiece16& packageNameToGenerate,
-                           const std::u16string& entryName,
-                           const Styleable* styleable,
-                           std::ostream* out);
+    void writeStyleableEntryForClass(ClassDefinitionWriter* outClassDef,
+                                     AnnotationProcessor* processor,
+                                     const StringPiece16& packageNameToGenerate,
+                                     const std::u16string& entryName,
+                                     const Styleable* styleable);
 
     bool skipSymbol(SymbolState state);
 
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index 2dc387b..e9e7881 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -56,13 +56,13 @@
     std::string output = out.str();
 
     EXPECT_NE(std::string::npos,
-              output.find("public static final int hey_man = 0x01020000;"));
+              output.find("public static final int hey_man=0x01020000;"));
 
     EXPECT_NE(std::string::npos,
-              output.find("public static final int[] hey_dude = {"));
+              output.find("public static final int[] hey_dude={"));
 
     EXPECT_NE(std::string::npos,
-              output.find("public static final int hey_dude_cool_attr = 0;"));
+              output.find("public static final int hey_dude_cool_attr=0;"));
 }
 
 TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) {
@@ -78,7 +78,7 @@
 
     std::string output = out.str();
     EXPECT_NE(std::string::npos, output.find("package com.android.internal;"));
-    EXPECT_NE(std::string::npos, output.find("public static final int one = 0x01020000;"));
+    EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
     EXPECT_EQ(std::string::npos, output.find("two"));
     EXPECT_EQ(std::string::npos, output.find("com_foo$two"));
 }
@@ -86,6 +86,7 @@
 TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) {
     std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
             .setPackageId(u"android", 0x01)
+            .addSimple(u"@android:attr/two", ResourceId(0x01010001))
             .addSimple(u"@android:^attr-private/one", ResourceId(0x01010000))
             .build();
 
@@ -116,7 +117,7 @@
         std::stringstream out;
         ASSERT_TRUE(generator.generate(u"android", &out));
         std::string output = out.str();
-        EXPECT_NE(std::string::npos, output.find("public static final int one = 0x01020000;"));
+        EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
         EXPECT_EQ(std::string::npos, output.find("two"));
         EXPECT_EQ(std::string::npos, output.find("three"));
     }
@@ -127,8 +128,8 @@
         std::stringstream out;
         ASSERT_TRUE(generator.generate(u"android", &out));
         std::string output = out.str();
-        EXPECT_NE(std::string::npos, output.find("public static final int one = 0x01020000;"));
-        EXPECT_NE(std::string::npos, output.find("public static final int two = 0x01020001;"));
+        EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
+        EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;"));
         EXPECT_EQ(std::string::npos, output.find("three"));
     }
 
@@ -138,9 +139,9 @@
         std::stringstream out;
         ASSERT_TRUE(generator.generate(u"android", &out));
         std::string output = out.str();
-        EXPECT_NE(std::string::npos, output.find("public static final int one = 0x01020000;"));
-        EXPECT_NE(std::string::npos, output.find("public static final int two = 0x01020001;"));
-        EXPECT_NE(std::string::npos, output.find("public static final int three = 0x01020002;"));
+        EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;"));
+        EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;"));
+        EXPECT_NE(std::string::npos, output.find("public static final int three=0x01020002;"));
     }
 }
 
@@ -194,8 +195,8 @@
     EXPECT_TRUE(generator.generate(u"android", &out));
 
     std::string output = out.str();
-    EXPECT_NE(std::string::npos, output.find("int foo_bar ="));
-    EXPECT_NE(std::string::npos, output.find("int foo_com_lib_bar ="));
+    EXPECT_NE(std::string::npos, output.find("int foo_bar="));
+    EXPECT_NE(std::string::npos, output.find("int foo_com_lib_bar="));
 }
 
 TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) {
@@ -218,7 +219,7 @@
      * @deprecated
      */
     @Deprecated
-    public static final int foo = 0x01010000;)EOF"));
+    public static final int foo=0x01010000;)EOF"));
 }
 
 TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {
diff --git a/tools/aapt2/java/ManifestClassGenerator.cpp b/tools/aapt2/java/ManifestClassGenerator.cpp
index 901a344..d963d89 100644
--- a/tools/aapt2/java/ManifestClassGenerator.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator.cpp
@@ -18,6 +18,7 @@
 #include "XmlDom.h"
 
 #include "java/AnnotationProcessor.h"
+#include "java/ClassDefinitionWriter.h"
 #include "java/ManifestClassGenerator.h"
 #include "util/Maybe.h"
 
@@ -58,8 +59,8 @@
     return result;
 }
 
-static bool writeSymbol(IDiagnostics* diag, const Source& source, xml::Element* el,
-                        std::ostream* out) {
+static bool writeSymbol(IDiagnostics* diag, ClassDefinitionWriter* outClassDef, const Source& source,
+                        xml::Element* el) {
     xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, u"name");
     if (!attr) {
         diag->error(DiagMessage(source) << "<" << el->name << "> must define 'android:name'");
@@ -72,18 +73,9 @@
         return false;
     }
 
-    *out << "\n";
-
-    if (!util::trimWhitespace(el->comment).empty()) {
-        AnnotationProcessor processor("    ");
-        processor.appendComment(el->comment);
-        *out << processor.buildComment() << "\n";
-        std::string annotations = processor.buildAnnotations();
-        if (!annotations.empty()) {
-            *out << annotations << "\n";
-        }
-    }
-    *out << "    public static final String " << result.value() << "=\"" << attr->value << "\";\n";
+    AnnotationProcessor processor;
+    processor.appendComment(el->comment);
+    outClassDef->addStringMember(result.value(), &processor, attr->value);
     return true;
 }
 
@@ -100,29 +92,32 @@
     }
 
     *out << "package " << package << ";\n\n"
-         << "public class Manifest {\n";
+         << "public final class Manifest {\n";
 
     bool error = false;
     std::vector<xml::Element*> children = el->getChildElements();
 
+    ClassDefinitionWriterOptions classOptions;
+    classOptions.useFinalQualifier = true;
+    classOptions.forceCreationIfEmpty = false;
 
     // First write out permissions.
-    *out << "  public static class permission {\n";
+    ClassDefinitionWriter classDef("permission", classOptions);
     for (xml::Element* childEl : children) {
         if (childEl->namespaceUri.empty() && childEl->name == u"permission") {
-            error |= !writeSymbol(diag, res->file.source, childEl, out);
+            error |= !writeSymbol(diag, &classDef, res->file.source, childEl);
         }
     }
-    *out << "  }\n";
+    classDef.writeToStream(out, "  ");
 
     // Next write out permission groups.
-    *out << "  public static class permission_group {\n";
+    classDef = ClassDefinitionWriter("permission_group", classOptions);
     for (xml::Element* childEl : children) {
         if (childEl->namespaceUri.empty() && childEl->name == u"permission-group") {
-            error |= !writeSymbol(diag, res->file.source, childEl, out);
+            error |= !writeSymbol(diag, &classDef, res->file.source, childEl);
         }
     }
-    *out << "  }\n";
+    classDef.writeToStream(out, "  ");
 
     *out << "}\n";
     return !error;
diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp
index 1b5bc05..4081287 100644
--- a/tools/aapt2/java/ManifestClassGenerator_test.cpp
+++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp
@@ -39,8 +39,9 @@
 
     std::string actual = out.str();
 
-    const size_t permissionClassPos = actual.find("public static class permission {");
-    const size_t permissionGroupClassPos = actual.find("public static class permission_group {");
+    const size_t permissionClassPos = actual.find("public static final class permission {");
+    const size_t permissionGroupClassPos =
+            actual.find("public static final class permission_group {");
     ASSERT_NE(std::string::npos, permissionClassPos);
     ASSERT_NE(std::string::npos, permissionGroupClassPos);
 
@@ -113,7 +114,7 @@
      * @hide
      * @SystemApi
      */
-    @android.annotations.SystemApi
+    @android.annotation.SystemApi
     public static final String SECRET="android.permission.SECRET";)EOF"));
 }
 
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index 11fcc5d..c7e603e 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -31,7 +31,7 @@
                                      const int sdkVersionToGenerate) {
     assert(sdkVersionToGenerate > config.sdkVersion);
     const auto endIter = entry->values.end();
-    auto iter = std::lower_bound(entry->values.begin(), endIter, config, cmp::lessThan);
+    auto iter = std::lower_bound(entry->values.begin(), endIter, config, cmp::lessThanConfig);
 
     // The source config came from this list, so it should be here.
     assert(iter != entry->values.end());
@@ -124,7 +124,7 @@
                                 auto iter = std::lower_bound(entry->values.begin(),
                                                              entry->values.end(),
                                                              newConfig,
-                                                             cmp::lessThan);
+                                                             cmp::lessThanConfig);
 
                                 entry->values.insert(
                                         iter,
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 0236e98..97be774 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -48,7 +48,9 @@
     std::string outputPath;
     std::string manifestPath;
     std::vector<std::string> includePaths;
+    std::vector<std::string> overlayFiles;
     Maybe<std::string> generateJavaClassPath;
+    std::set<std::string> extraJavaPackages;
     Maybe<std::string> generateProguardRulesPath;
     bool noAutoVersion = false;
     bool staticLib = false;
@@ -87,9 +89,11 @@
     }
 };
 
-struct LinkCommand {
-    LinkOptions mOptions;
-    LinkContext mContext;
+class LinkCommand {
+public:
+    LinkCommand(const LinkOptions& options) :
+            mOptions(options), mContext(), mFinalTable() {
+    }
 
     std::string buildResourceFileName(const ResourceFile& resFile) {
         std::stringstream out;
@@ -116,8 +120,7 @@
         AssetManagerSymbolTableBuilder builder;
         for (const std::string& path : mOptions.includePaths) {
             if (mOptions.verbose) {
-                mContext.getDiagnostics()->note(
-                        DiagMessage(Source{ path }) << "loading include path");
+                mContext.getDiagnostics()->note(DiagMessage(path) << "loading include path");
             }
 
             std::unique_ptr<android::AssetManager> assetManager =
@@ -125,7 +128,7 @@
             int32_t cookie = 0;
             if (!assetManager->addAssetPath(android::String8(path.data(), path.size()), &cookie)) {
                 mContext.getDiagnostics()->error(
-                        DiagMessage(Source{ path }) << "failed to load include path");
+                        DiagMessage(path) << "failed to load include path");
                 return {};
             }
             builder.add(std::move(assetManager));
@@ -140,12 +143,12 @@
         std::string errorStr;
         Maybe<android::FileMap> map = file::mmapPath(input, &errorStr);
         if (!map) {
-            mContext.getDiagnostics()->error(DiagMessage(Source{ input }) << errorStr);
+            mContext.getDiagnostics()->error(DiagMessage(input) << errorStr);
             return {};
         }
 
         std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
-        BinaryResourceParser parser(&mContext, table.get(), Source{ input },
+        BinaryResourceParser parser(&mContext, table.get(), Source(input),
                                     map.value().getDataPtr(), map.value().getDataLength());
         if (!parser.parse()) {
             return {};
@@ -159,11 +162,11 @@
     std::unique_ptr<XmlResource> loadXml(const std::string& path) {
         std::ifstream fin(path, std::ifstream::binary);
         if (!fin) {
-            mContext.getDiagnostics()->error(DiagMessage(Source{ path }) << strerror(errno));
+            mContext.getDiagnostics()->error(DiagMessage(path) << strerror(errno));
             return {};
         }
 
-        return xml::inflate(&fin, mContext.getDiagnostics(), Source{ path });
+        return xml::inflate(&fin, mContext.getDiagnostics(), Source(path));
     }
 
     /**
@@ -254,9 +257,9 @@
         return {};
     }
 
-    bool verifyNoExternalPackages(ResourceTable* table) {
+    bool verifyNoExternalPackages() {
         bool error = false;
-        for (const auto& package : table->packages) {
+        for (const auto& package : mFinalTable.packages) {
             if (mContext.getCompilationPackage() != package->name ||
                     !package->id || package->id.value() != mContext.getPackageId()) {
                 // We have a package that is not related to the one we're building!
@@ -400,6 +403,103 @@
         return true;
     }
 
+    bool mergeStaticLibrary(const std::string& input) {
+        // TODO(adamlesinski): Load resources from a static library APK and merge the table into
+        // TableMerger.
+        mContext.getDiagnostics()->warn(DiagMessage()
+                                        << "linking static libraries not supported yet: "
+                                        << input);
+        return true;
+    }
+
+    bool mergeResourceTable(const std::string& input, bool override) {
+        if (mOptions.verbose) {
+            mContext.getDiagnostics()->note(DiagMessage() << "linking " << input);
+        }
+
+        std::unique_ptr<ResourceTable> table = loadTable(input);
+        if (!table) {
+            return false;
+        }
+
+        if (!mTableMerger->merge(Source(input), table.get(), override)) {
+            return false;
+        }
+        return true;
+    }
+
+    bool mergeCompiledFile(const std::string& input, ResourceFile&& file, bool override) {
+        if (file.name.package.empty()) {
+            file.name.package = mContext.getCompilationPackage().toString();
+        }
+
+        ResourceNameRef resName = file.name;
+
+        Maybe<ResourceName> mangledName = mContext.getNameMangler()->mangleName(file.name);
+        if (mangledName) {
+            resName = mangledName.value();
+        }
+
+        std::function<int(Value*,Value*)> resolver;
+        if (override) {
+            resolver = [](Value* a, Value* b) -> int {
+                int result = ResourceTable::resolveValueCollision(a, b);
+                if (result == 0) {
+                    // Always accept the new value if it would normally conflict (override).
+                    result = 1;
+                }
+                return result;
+            };
+        } else {
+            // Otherwise use the default resolution.
+            resolver = ResourceTable::resolveValueCollision;
+        }
+
+        // Add this file to the table.
+        if (!mFinalTable.addFileReference(resName, file.config, file.source,
+                                          util::utf8ToUtf16(buildResourceFileName(file)),
+                                          resolver, mContext.getDiagnostics())) {
+            return false;
+        }
+
+        // Add the exports of this file to the table.
+        for (SourcedResourceName& exportedSymbol : file.exportedSymbols) {
+            if (exportedSymbol.name.package.empty()) {
+                exportedSymbol.name.package = mContext.getCompilationPackage().toString();
+            }
+
+            ResourceNameRef resName = exportedSymbol.name;
+
+            Maybe<ResourceName> mangledName = mContext.getNameMangler()->mangleName(
+                    exportedSymbol.name);
+            if (mangledName) {
+                resName = mangledName.value();
+            }
+
+            std::unique_ptr<Id> id = util::make_unique<Id>();
+            id->setSource(file.source.withLine(exportedSymbol.line));
+            bool result = mFinalTable.addResourceAllowMangled(resName, {}, std::move(id),
+                    mContext.getDiagnostics());
+            if (!result) {
+                return false;
+            }
+        }
+
+        mFilesToProcess.insert(FileToProcess{ std::move(file), Source(input) });
+        return true;
+    }
+
+    bool processFile(const std::string& input, bool override) {
+        if (util::stringEndsWith<char>(input, ".apk")) {
+            return mergeStaticLibrary(input);
+        } else if (util::stringEndsWith<char>(input, ".arsc.flat")) {
+            return mergeResourceTable(input, override);
+        } else if (Maybe<ResourceFile> maybeF = loadFileExportHeader(input)) {
+            return mergeCompiledFile(input, std::move(maybeF.value()), override);
+        }
+        return false;
+    }
+
     int run(const std::vector<std::string>& inputFiles) {
         // Load the AndroidManifest.xml
         std::unique_ptr<XmlResource> manifestXml = loadXml(mOptions.manifestPath);
@@ -437,82 +537,25 @@
             return 1;
         }
 
+        mTableMerger = util::make_unique<TableMerger>(&mContext, &mFinalTable);
+
         if (mOptions.verbose) {
             mContext.getDiagnostics()->note(
                     DiagMessage() << "linking package '" << mContext.mCompilationPackage << "' "
                                   << "with package ID " << std::hex << (int) mContext.mPackageId);
         }
 
-        ResourceTable mergedTable;
-        TableMerger tableMerger(&mContext, &mergedTable);
-
-        struct FilesToProcess {
-            Source source;
-            ResourceFile file;
-        };
-
         bool error = false;
-        std::queue<FilesToProcess> filesToProcess;
+
         for (const std::string& input : inputFiles) {
-            if (util::stringEndsWith<char>(input, ".apk")) {
-                // TODO(adamlesinski): Load resources from a static library APK
-                //                     Merge the table into TableMerger.
+            if (!processFile(input, false)) {
+                error = true;
+            }
+        }
 
-            } else if (util::stringEndsWith<char>(input, ".arsc.flat")) {
-                if (mOptions.verbose) {
-                    mContext.getDiagnostics()->note(DiagMessage() << "linking " << input);
-                }
-
-                std::unique_ptr<ResourceTable> table = loadTable(input);
-                if (!table) {
-                    return 1;
-                }
-
-                if (!tableMerger.merge(Source(input), table.get())) {
-                    return 1;
-                }
-
-            } else {
-                // Extract the exported IDs here so we can build the resource table.
-                if (Maybe<ResourceFile> maybeF = loadFileExportHeader(input)) {
-                    ResourceFile& f = maybeF.value();
-
-                    if (f.name.package.empty()) {
-                        f.name.package = mContext.getCompilationPackage().toString();
-                    }
-
-                    Maybe<ResourceName> mangledName = mContext.getNameMangler()->mangleName(f.name);
-
-                    // Add this file to the table.
-                    if (!mergedTable.addFileReference(mangledName ? mangledName.value() : f.name,
-                                                      f.config, f.source,
-                                                      util::utf8ToUtf16(buildResourceFileName(f)),
-                                                      mContext.getDiagnostics())) {
-                        error = true;
-                    }
-
-                    // Add the exports of this file to the table.
-                    for (SourcedResourceName& exportedSymbol : f.exportedSymbols) {
-                        if (exportedSymbol.name.package.empty()) {
-                            exportedSymbol.name.package = mContext.getCompilationPackage()
-                                    .toString();
-                        }
-
-                        Maybe<ResourceName> mangledName = mContext.getNameMangler()->mangleName(
-                                exportedSymbol.name);
-                        std::unique_ptr<Id> id = util::make_unique<Id>();
-                        id->setSource(f.source.withLine(exportedSymbol.line));
-                        if (!mergedTable.addResourceAllowMangled(
-                                mangledName ? mangledName.value() : exportedSymbol.name,
-                                {}, std::move(id), mContext.getDiagnostics())) {
-                            error = true;
-                        }
-                    }
-
-                    filesToProcess.push(FilesToProcess{ Source(input), std::move(f) });
-                } else {
-                    return 1;
-                }
+        for (const std::string& input : mOptions.overlayFiles) {
+            if (!processFile(input, true)) {
+                error = true;
             }
         }
 
@@ -521,13 +564,13 @@
             return 1;
         }
 
-        if (!verifyNoExternalPackages(&mergedTable)) {
+        if (!verifyNoExternalPackages()) {
             return 1;
         }
 
         if (!mOptions.staticLib) {
             PrivateAttributeMover mover;
-            if (!mover.consume(&mContext, &mergedTable)) {
+            if (!mover.consume(&mContext, &mFinalTable)) {
                 mContext.getDiagnostics()->error(
                         DiagMessage() << "failed moving private attributes");
                 return 1;
@@ -536,22 +579,22 @@
 
         {
             IdAssigner idAssigner;
-            if (!idAssigner.consume(&mContext, &mergedTable)) {
+            if (!idAssigner.consume(&mContext, &mFinalTable)) {
                 mContext.getDiagnostics()->error(DiagMessage() << "failed assigning IDs");
                 return 1;
             }
         }
 
-        mContext.mNameMangler = util::make_unique<NameMangler>(
-                NameManglerPolicy{ mContext.mCompilationPackage, tableMerger.getMergedPackages() });
+        mContext.mNameMangler = util::make_unique<NameMangler>(NameManglerPolicy{
+                mContext.mCompilationPackage, mTableMerger->getMergedPackages() });
         mContext.mSymbols = JoinedSymbolTableBuilder()
-                .addSymbolTable(util::make_unique<SymbolTableWrapper>(&mergedTable))
+                .addSymbolTable(util::make_unique<SymbolTableWrapper>(&mFinalTable))
                 .addSymbolTable(std::move(mContext.mSymbols))
                 .build();
 
         {
             ReferenceLinker linker;
-            if (!linker.consume(&mContext, &mergedTable)) {
+            if (!linker.consume(&mContext, &mFinalTable)) {
                 mContext.getDiagnostics()->error(DiagMessage() << "failed linking references");
                 return 1;
             }
@@ -597,20 +640,19 @@
             }
         }
 
-        for (; !filesToProcess.empty(); filesToProcess.pop()) {
-            FilesToProcess& f = filesToProcess.front();
-            if (f.file.name.type != ResourceType::kRaw &&
-                    util::stringEndsWith<char>(f.source.path, ".xml.flat")) {
+        for (const FileToProcess& file : mFilesToProcess) {
+            if (file.file.name.type != ResourceType::kRaw &&
+                    util::stringEndsWith<char>(file.source.path, ".xml.flat")) {
                 if (mOptions.verbose) {
-                    mContext.getDiagnostics()->note(DiagMessage() << "linking " << f.source.path);
+                    mContext.getDiagnostics()->note(DiagMessage() << "linking " << file.source.path);
                 }
 
-                std::unique_ptr<XmlResource> xmlRes = loadBinaryXmlSkipFileExport(f.source.path);
+                std::unique_ptr<XmlResource> xmlRes = loadBinaryXmlSkipFileExport(file.source.path);
                 if (!xmlRes) {
                     return 1;
                 }
 
-                xmlRes->file = std::move(f.file);
+                xmlRes->file = std::move(file.file);
 
                 XmlReferenceLinker xmlLinker;
                 if (xmlLinker.consume(&mContext, xmlRes.get())) {
@@ -630,7 +672,7 @@
                     }
 
                     if (!mOptions.noAutoVersion) {
-                        Maybe<ResourceTable::SearchResult> result = mergedTable.findResource(
+                        Maybe<ResourceTable::SearchResult> result = mFinalTable.findResource(
                                 xmlRes->file.name);
                         for (int sdkLevel : xmlLinker.getSdkLevels()) {
                             if (sdkLevel > xmlRes->file.config.sdkVersion &&
@@ -638,7 +680,7 @@
                                                                     xmlRes->file.config,
                                                                     sdkLevel)) {
                                 xmlRes->file.config.sdkVersion = sdkLevel;
-                                if (!mergedTable.addFileReference(xmlRes->file.name,
+                                if (!mFinalTable.addFileReference(xmlRes->file.name,
                                                                   xmlRes->file.config,
                                                                   xmlRes->file.source,
                                                                   util::utf8ToUtf16(
@@ -661,10 +703,11 @@
                 }
             } else {
                 if (mOptions.verbose) {
-                    mContext.getDiagnostics()->note(DiagMessage() << "copying " << f.source.path);
+                    mContext.getDiagnostics()->note(DiagMessage() << "copying "
+                                                    << file.source.path);
                 }
 
-                if (!copyFileToArchive(f.source.path, buildResourceFileName(f.file), 0,
+                if (!copyFileToArchive(file.source.path, buildResourceFileName(file.file), 0,
                                        archiveWriter.get())) {
                     error = true;
                 }
@@ -678,13 +721,13 @@
 
         if (!mOptions.noAutoVersion) {
             AutoVersioner versioner;
-            if (!versioner.consume(&mContext, &mergedTable)) {
+            if (!versioner.consume(&mContext, &mFinalTable)) {
                 mContext.getDiagnostics()->error(DiagMessage() << "failed versioning styles");
                 return 1;
             }
         }
 
-        if (!flattenTable(&mergedTable, archiveWriter.get())) {
+        if (!flattenTable(&mFinalTable, archiveWriter.get())) {
             mContext.getDiagnostics()->error(DiagMessage() << "failed to write resources.arsc");
             return 1;
         }
@@ -695,27 +738,30 @@
                 options.useFinal = false;
             }
 
+            StringPiece16 actualPackage = mContext.getCompilationPackage();
+            StringPiece16 outputPackage = mContext.getCompilationPackage();
+
             if (mOptions.privateSymbols) {
                 // If we defined a private symbols package, we only emit Public symbols
                 // to the original package, and private and public symbols to the private package.
 
                 options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
-                if (!writeJavaFile(&mergedTable, mContext.getCompilationPackage(),
+                if (!writeJavaFile(&mFinalTable, mContext.getCompilationPackage(),
                                    mContext.getCompilationPackage(), options)) {
                     return 1;
                 }
 
                 options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate;
-                if (!writeJavaFile(&mergedTable, mContext.getCompilationPackage(),
-                                   mOptions.privateSymbols.value(), options)) {
-                    return 1;
-                }
+                outputPackage = mOptions.privateSymbols.value();
+            }
 
-            } else {
-                // Emit Everything.
+            if (!writeJavaFile(&mFinalTable, actualPackage, outputPackage, options)) {
+                return 1;
+            }
 
-                if (!writeJavaFile(&mergedTable, mContext.getCompilationPackage(),
-                                   mContext.getCompilationPackage(), options)) {
+            for (const std::string& extraPackage : mOptions.extraJavaPackages) {
+                if (!writeJavaFile(&mFinalTable, actualPackage, util::utf8ToUtf16(extraPackage),
+                                   options)) {
                     return 1;
                 }
             }
@@ -728,10 +774,10 @@
         }
 
         if (mOptions.verbose) {
-            Debug::printTable(&mergedTable);
-            for (; !tableMerger.getFileMergeQueue()->empty();
-                    tableMerger.getFileMergeQueue()->pop()) {
-                const FileToMerge& f = tableMerger.getFileMergeQueue()->front();
+            Debug::printTable(&mFinalTable);
+            for (; !mTableMerger->getFileMergeQueue()->empty();
+                    mTableMerger->getFileMergeQueue()->pop()) {
+                const FileToMerge& f = mTableMerger->getFileMergeQueue()->front();
                 mContext.getDiagnostics()->note(
                         DiagMessage() << f.srcPath << " -> " << f.dstPath << " from (0x"
                                       << std::hex << (uintptr_t) f.srcTable << std::dec);
@@ -740,17 +786,40 @@
 
         return 0;
     }
+
+private:
+    LinkOptions mOptions;
+    LinkContext mContext;
+    ResourceTable mFinalTable;
+    std::unique_ptr<TableMerger> mTableMerger;
+
+    struct FileToProcess {
+        ResourceFile file;
+        Source source;
+    };
+
+    struct FileToProcessComparator {
+        bool operator()(const FileToProcess& a, const FileToProcess& b) {
+            return std::tie(a.file.name, a.file.config) < std::tie(b.file.name, b.file.config);
+        }
+    };
+
+    std::set<FileToProcess, FileToProcessComparator> mFilesToProcess;
 };
 
 int link(const std::vector<StringPiece>& args) {
     LinkOptions options;
     Maybe<std::string> privateSymbolsPackage;
     Maybe<std::string> minSdkVersion, targetSdkVersion;
+    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. "
+                              "The last conflicting resource given takes precedence.",
+                              &options.overlayFiles)
             .optionalFlag("--java", "Directory in which to generate R.java",
                           &options.generateJavaClassPath)
             .optionalFlag("--proguard", "Output file for generated Proguard rules",
@@ -770,6 +839,8 @@
                           "private symbols.\n"
                           "If not specified, public and private symbols will use the application's "
                           "package name", &privateSymbolsPackage)
+            .optionalFlagList("--extra-packages", "Generate the same R.java but with different "
+                              "package names", &extraJavaPackages)
             .optionalSwitch("-v", "Enables verbose logging", &options.verbose);
 
     if (!flags.parse("aapt2 link", args, &std::cerr)) {
@@ -788,7 +859,15 @@
         options.targetSdkVersionDefault = util::utf8ToUtf16(targetSdkVersion.value());
     }
 
-    LinkCommand cmd = { options };
+    // 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());
+        }
+    }
+
+    LinkCommand cmd(options);
     return cmd.run(flags.getArgs());
 }
 
diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h
index 2cc8d9f..7b3fc35 100644
--- a/tools/aapt2/link/Linkers.h
+++ b/tools/aapt2/link/Linkers.h
@@ -38,26 +38,61 @@
     bool consume(IAaptContext* context, ResourceTable* table) override;
 };
 
-struct PrivateAttributeMover : public IResourceTableConsumer {
-    bool consume(IAaptContext* context, ResourceTable* table) override;
-};
-
 struct XmlAutoVersioner : public IXmlResourceConsumer {
     bool consume(IAaptContext* context, XmlResource* resource) override;
 };
 
+/**
+ * If any attribute resource values are defined as public, this consumer will move all private
+ * attribute resource values to a private ^private-attr type, avoiding backwards compatibility
+ * issues with new apps running on old platforms.
+ *
+ * The Android platform ignores resource attributes it doesn't recognize, so an app developer can
+ * use new attributes in their layout XML files without worrying about versioning. This assumption
+ * actually breaks on older platforms. OEMs may add private attributes that are used internally.
+ * AAPT originally assigned all private attributes IDs immediately proceeding the public attributes'
+ * IDs.
+ *
+ * This means that on a newer Android platform, an ID previously assigned to a private attribute
+ * may end up assigned to a public attribute.
+ *
+ * App developers assume using the newer attribute is safe on older platforms because it will
+ * be ignored. Instead, the platform thinks the new attribute is an older, private attribute and
+ * will interpret it as such. This leads to unintended styling and exceptions thrown due to
+ * unexpected types.
+ *
+ * By moving the private attributes to a completely different type, this ID conflict will never
+ * occur.
+ */
+struct PrivateAttributeMover : public IResourceTableConsumer {
+    bool consume(IAaptContext* context, ResourceTable* table) override;
+};
+
+/**
+ * Resolves all references to resources in the ResourceTable and assigns them IDs.
+ * The ResourceTable must already have IDs assigned to each resource.
+ * Once the ResourceTable is processed by this linker, it is ready to be flattened.
+ */
 struct ReferenceLinker : public IResourceTableConsumer {
     bool consume(IAaptContext* context, ResourceTable* table) override;
 };
 
-class XmlReferenceLinker : IXmlResourceConsumer {
+/**
+ * Resolves attributes in the XmlResource and compiles string values to resource values.
+ * Once an XmlResource is processed by this linker, it is ready to be flattened.
+ */
+class XmlReferenceLinker : public IXmlResourceConsumer {
 private:
     std::set<int> mSdkLevelsFound;
 
 public:
     bool consume(IAaptContext* context, XmlResource* resource) override;
 
-    const std::set<int>& getSdkLevels() const {
+    /**
+     * Once the XmlResource has been consumed, this returns the various SDK levels in which
+     * framework attributes used within the XML document were defined.
+     */
+    inline const std::set<int>& getSdkLevels() const {
         return mSdkLevelsFound;
     }
 };
diff --git a/tools/aapt2/link/ReferenceLinkerVisitor.h b/tools/aapt2/link/ReferenceLinkerVisitor.h
index c70531b..a4cb596 100644
--- a/tools/aapt2/link/ReferenceLinkerVisitor.h
+++ b/tools/aapt2/link/ReferenceLinkerVisitor.h
@@ -80,7 +80,7 @@
                 return;
             }
 
-            DiagMessage errorMsg;
+            DiagMessage errorMsg(reference->getSource());
             errorMsg << "reference to " << reference->name.value();
             if (realName) {
                 errorMsg << " (aka " << realName.value() << ")";
@@ -92,7 +92,7 @@
         }
 
         if (!mSymbols->findById(reference->id.value())) {
-            mContext->getDiagnostics()->error(DiagMessage()
+            mContext->getDiagnostics()->error(DiagMessage(reference->getSource())
                                               << "reference to " << reference->id.value()
                                               << " was not found");
             mError = true;
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index 636c2ba..a06a1bf 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -34,7 +34,10 @@
     assert(mMasterPackage && "package name or ID already taken");
 }
 
-bool TableMerger::merge(const Source& src, ResourceTable* table) {
+/**
+ * This will merge packages with the same package name (or no package name).
+ */
+bool TableMerger::merge(const Source& src, ResourceTable* table, bool overrideExisting) {
     const uint8_t desiredPackageId = mContext->getPackageId();
 
     bool error = false;
@@ -46,18 +49,37 @@
             continue;
         }
 
-        bool manglePackage = false;
-        if (!package->name.empty() && mContext->getCompilationPackage() != package->name) {
-            manglePackage = true;
-            mMergedPackages.insert(package->name);
+        if (package->name.empty() || mContext->getCompilationPackage() == package->name) {
+            // Merge here. Once the entries are merged and mangled, any references to
+            // them are still valid. This is because un-mangled references are
+            // mangled, then looked up at resolution time.
+            // Also, when linking, we convert references with no package name to use
+            // the compilation package name.
+            if (!doMerge(src, table, package.get(), false, overrideExisting)) {
+                error = true;
+            }
+        }
+    }
+    return !error;
+}
+
+/**
+ * This will merge and mangle resources from a static library.
+ */
+bool TableMerger::mergeAndMangle(const Source& src, const StringPiece16& packageName,
+                                 ResourceTable* table) {
+    bool error = false;
+    for (auto& package : table->packages) {
+        // Warn of packages with an unrelated ID.
+        if (packageName != package->name) {
+            mContext->getDiagnostics()->warn(DiagMessage(src)
+                                             << "ignoring package " << package->name);
+            continue;
         }
 
-        // Merge here. Once the entries are merged and mangled, any references to
-        // them are still valid. This is because un-mangled references are
-        // mangled, then looked up at resolution time.
-        // Also, when linking, we convert references with no package name to use
-        // the compilation package name.
-        if (!doMerge(src, table, package.get(), manglePackage)) {
+        bool mangle = packageName != mContext->getCompilationPackage();
+        mMergedPackages.insert(package->name);
+        if (!doMerge(src, table, package.get(), mangle, false)) {
             error = true;
         }
     }
@@ -65,7 +87,8 @@
 }
 
 bool TableMerger::doMerge(const Source& src, ResourceTable* srcTable,
-                          ResourceTablePackage* srcPackage, const bool manglePackage) {
+                          ResourceTablePackage* srcPackage, const bool manglePackage,
+                          const bool overrideExisting) {
     bool error = false;
 
     for (auto& srcType : srcPackage->types) {
@@ -122,12 +145,12 @@
 
             for (ResourceConfigValue& srcValue : srcEntry->values) {
                 auto iter = std::lower_bound(dstEntry->values.begin(), dstEntry->values.end(),
-                                             srcValue.config, cmp::lessThan);
+                                             srcValue.config, cmp::lessThanConfig);
 
                 if (iter != dstEntry->values.end() && iter->config == srcValue.config) {
                     const int collisionResult = ResourceTable::resolveValueCollision(
                             iter->value.get(), srcValue.value.get());
-                    if (collisionResult == 0) {
+                    if (collisionResult == 0 && !overrideExisting) {
                         // Error!
                         ResourceNameRef resourceName(srcPackage->name,
                                                      srcType->type,
diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h
index 157c16e..a2c9dbf 100644
--- a/tools/aapt2/link/TableMerger.h
+++ b/tools/aapt2/link/TableMerger.h
@@ -60,7 +60,15 @@
         return mMergedPackages;
     }
 
-    bool merge(const Source& src, ResourceTable* table);
+    /**
+     * Merges resources from the same or empty package. This is for local sources.
+     */
+    bool merge(const Source& src, ResourceTable* table, bool overrideExisting);
+
+    /**
+     * Merges resources from the given package, mangling the name. This is for static libraries.
+     */
+    bool mergeAndMangle(const Source& src, const StringPiece16& package, ResourceTable* table);
 
 private:
     IAaptContext* mContext;
@@ -71,7 +79,7 @@
     std::queue<FileToMerge> mFilesToMerge;
 
     bool doMerge(const Source& src, ResourceTable* srcTable, ResourceTablePackage* srcPackage,
-                 const bool manglePackage);
+                 const bool manglePackage, const bool overrideExisting);
 
     std::unique_ptr<Value> cloneAndMangle(ResourceTable* table, const std::u16string& package,
                                           Value* value);
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index fa7ce86..b7ffba7 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -59,8 +59,8 @@
     ResourceTable finalTable;
     TableMerger merger(mContext.get(), &finalTable);
 
-    ASSERT_TRUE(merger.merge({}, tableA.get()));
-    ASSERT_TRUE(merger.merge({}, tableB.get()));
+    ASSERT_TRUE(merger.merge({}, tableA.get(), false));
+    ASSERT_TRUE(merger.mergeAndMangle({}, u"com.app.b", tableB.get()));
 
     EXPECT_TRUE(merger.getMergedPackages().count(u"com.app.b") != 0);
 
@@ -89,8 +89,8 @@
     ResourceTable finalTable;
     TableMerger merger(mContext.get(), &finalTable);
 
-    ASSERT_TRUE(merger.merge({}, tableA.get()));
-    ASSERT_TRUE(merger.merge({}, tableB.get()));
+    ASSERT_TRUE(merger.merge({}, tableA.get(), false));
+    ASSERT_TRUE(merger.mergeAndMangle({}, u"com.app.b", tableB.get()));
 
     FileReference* f = test::getValue<FileReference>(&finalTable, u"@com.app.a:xml/file");
     ASSERT_NE(f, nullptr);
diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp
index 147b9bf..caab9b8 100644
--- a/tools/aapt2/link/XmlReferenceLinker.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker.cpp
@@ -33,6 +33,7 @@
 private:
     IAaptContext* mContext;
     ISymbolTable* mSymbols;
+    Source mSource;
     std::set<int>* mSdkLevelsFound;
     ReferenceLinkerVisitor mReferenceLinkerVisitor;
     bool mError = false;
@@ -40,13 +41,14 @@
 public:
     using xml::PackageAwareVisitor::visit;
 
-    XmlReferenceLinkerVisitor(IAaptContext* context, ISymbolTable* symbols,
+    XmlReferenceLinkerVisitor(IAaptContext* context, ISymbolTable* symbols, const Source& source,
                               std::set<int>* sdkLevelsFound) :
-            mContext(context), mSymbols(symbols), mSdkLevelsFound(sdkLevelsFound),
+            mContext(context), mSymbols(symbols), mSource(source), mSdkLevelsFound(sdkLevelsFound),
             mReferenceLinkerVisitor(context, symbols, this) {
     }
 
     void visit(xml::Element* el) override {
+        const Source source = mSource.withLine(el->lineNumber);
         for (xml::Attribute& attr : el->attributes) {
             Maybe<std::u16string> maybePackage =
                     util::extractPackageFromNamespace(attr.namespaceUri);
@@ -76,15 +78,16 @@
                             !(attribute->typeMask & android::ResTable_map::TYPE_STRING)) {
                         // We won't be able to encode this as a string.
                         mContext->getDiagnostics()->error(
-                                DiagMessage() << "'" << attr.value << "' "
-                                              << "is incompatible with attribute "
-                                              << package << ":" << attr.name << " " << *attribute);
+                                DiagMessage(source) << "'" << attr.value << "' "
+                                                    << "is incompatible with attribute "
+                                                    << package << ":" << attr.name << " "
+                                                    << *attribute);
                         mError = true;
                     }
                 } else {
-                    mContext->getDiagnostics()->error(
-                            DiagMessage() << "attribute '" << package << ":" << attr.name
-                                          << "' was not found");
+                    mContext->getDiagnostics()->error(DiagMessage(source)
+                                                      << "attribute '" << package << ":"
+                                                      << attr.name << "' was not found");
                     mError = true;
 
                 }
@@ -95,6 +98,7 @@
 
             if (attr.compiledValue) {
                 // With a compiledValue, we must resolve the reference and assign it an ID.
+                attr.compiledValue->setSource(source);
                 attr.compiledValue->accept(&mReferenceLinkerVisitor);
             }
         }
@@ -123,7 +127,8 @@
 
 bool XmlReferenceLinker::consume(IAaptContext* context, XmlResource* resource) {
     mSdkLevelsFound.clear();
-    XmlReferenceLinkerVisitor visitor(context, context->getExternalSymbols(), &mSdkLevelsFound);
+    XmlReferenceLinkerVisitor visitor(context, context->getExternalSymbols(), resource->file.source,
+                                      &mSdkLevelsFound);
     if (resource->root) {
         resource->root->accept(&visitor);
         return !visitor.hasError();
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 7309396..bb33ea7 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -55,7 +55,7 @@
     if (name.type == ResourceType::kAttr || name.type == ResourceType::kAttrPrivate) {
         const ConfigDescription kDefaultConfig;
         auto iter = std::lower_bound(sr.entry->values.begin(), sr.entry->values.end(),
-                                     kDefaultConfig, cmp::lessThan);
+                                     kDefaultConfig, cmp::lessThanConfig);
 
         if (iter != sr.entry->values.end() && iter->config == kDefaultConfig) {
             // This resource has an Attribute.
@@ -77,16 +77,8 @@
 }
 
 
-static std::shared_ptr<ISymbolTable::Symbol> lookupIdInTable(const android::ResTable& table,
-                                                             ResourceId id) {
-    android::Res_value val = {};
-    ssize_t block = table.getResource(id.id, &val, true);
-    if (block >= 0) {
-        std::shared_ptr<ISymbolTable::Symbol> s = std::make_shared<ISymbolTable::Symbol>();
-        s->id = id;
-        return s;
-    }
-
+static std::shared_ptr<ISymbolTable::Symbol> lookupAttributeInTable(const android::ResTable& table,
+                                                                    ResourceId id) {
     // Try as a bag.
     const android::ResTable::bag_entry* entry;
     ssize_t count = table.lockBag(id.id, &entry);
@@ -148,14 +140,23 @@
     for (const auto& asset : mAssets) {
         const android::ResTable& table = asset->getResources(false);
         StringPiece16 typeStr = toString(name.type);
+        uint32_t typeSpecFlags = 0;
         ResourceId resId = table.identifierForName(name.entry.data(), name.entry.size(),
                                                    typeStr.data(), typeStr.size(),
-                                                   name.package.data(), name.package.size());
+                                                   name.package.data(), name.package.size(),
+                                                   &typeSpecFlags);
         if (!resId.isValid()) {
             continue;
         }
 
-        std::shared_ptr<Symbol> s = lookupIdInTable(table, resId);
+        std::shared_ptr<Symbol> s;
+        if (name.type == ResourceType::kAttr) {
+            s = lookupAttributeInTable(table, resId);
+        } else {
+            s = std::make_shared<Symbol>();
+            s->id = resId;
+        }
+
         if (s) {
             mCache.put(name, s);
             return s.get();
@@ -173,7 +174,28 @@
     for (const auto& asset : mAssets) {
         const android::ResTable& table = asset->getResources(false);
 
-        std::shared_ptr<Symbol> s = lookupIdInTable(table, id);
+        android::ResTable::resource_name name;
+        if (!table.getResourceName(id.id, true, &name)) {
+            continue;
+        }
+
+        bool isAttr = false;
+        if (name.type) {
+            if (const ResourceType* t = parseResourceType(StringPiece16(name.type, name.typeLen))) {
+                isAttr = (*t == ResourceType::kAttr);
+            }
+        } else if (name.type8) {
+            isAttr = (StringPiece(name.type8, name.typeLen) == "attr");
+        }
+
+        std::shared_ptr<Symbol> s;
+        if (isAttr) {
+            s = lookupAttributeInTable(table, id);
+        } else {
+            s = std::make_shared<Symbol>();
+            s->id = id;
+        }
+
         if (s) {
             mIdCache.put(id, s);
             return s.get();
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 0d17e84..3048334 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -304,6 +304,11 @@
         return false;
     }
 
+    // There can be multiple packages in a table, so
+    // clear the type and key pool in case they were set from a previous package.
+    mTypePool.uninit();
+    mKeyPool.uninit();
+
     ResChunkPullParser parser(getChunkData(&packageHeader->header),
                               getChunkDataLen(&packageHeader->header));
     while (ResChunkPullParser::isGoodEvent(parser.next())) {
diff --git a/tools/aapt2/util/Comparators.h b/tools/aapt2/util/Comparators.h
index 652018e..0ee0bf3 100644
--- a/tools/aapt2/util/Comparators.h
+++ b/tools/aapt2/util/Comparators.h
@@ -17,13 +17,20 @@
 #ifndef AAPT_UTIL_COMPARATORS_H
 #define AAPT_UTIL_COMPARATORS_H
 
+#include "ConfigDescription.h"
+#include "ResourceTable.h"
+
 namespace aapt {
 namespace cmp {
 
-inline bool lessThan(const ResourceConfigValue& a, const ConfigDescription& b) {
+inline bool lessThanConfig(const ResourceConfigValue& a, const ConfigDescription& b) {
     return a.config < b;
 }
 
+inline bool lessThanType(const std::unique_ptr<ResourceTableType>& a, ResourceType b) {
+    return a->type < b;
+}
+
 } // namespace cmp
 } // namespace aapt
 
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index 80552a5..324afb3 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -229,11 +229,12 @@
     private:
         friend class Tokenizer<Char>;
 
-        iterator(BasicStringPiece<Char> s, Char sep, BasicStringPiece<Char> tok);
+        iterator(BasicStringPiece<Char> s, Char sep, BasicStringPiece<Char> tok, bool end);
 
-        BasicStringPiece<Char> str;
-        Char separator;
-        BasicStringPiece<Char> token;
+        BasicStringPiece<Char> mStr;
+        Char mSeparator;
+        BasicStringPiece<Char> mToken;
+        bool mEnd;
     };
 
     Tokenizer(BasicStringPiece<Char> str, Char sep);
@@ -252,36 +253,38 @@
 
 template <typename Char>
 typename Tokenizer<Char>::iterator& Tokenizer<Char>::iterator::operator++() {
-    const Char* start = token.end();
-    const Char* end = str.end();
+    const Char* start = mToken.end();
+    const Char* end = mStr.end();
     if (start == end) {
-        token.assign(token.end(), 0);
+        mEnd = true;
+        mToken.assign(mToken.end(), 0);
         return *this;
     }
 
     start += 1;
     const Char* current = start;
     while (current != end) {
-        if (*current == separator) {
-            token.assign(start, current - start);
+        if (*current == mSeparator) {
+            mToken.assign(start, current - start);
             return *this;
         }
         ++current;
     }
-    token.assign(start, end - start);
+    mToken.assign(start, end - start);
     return *this;
 }
 
 template <typename Char>
 inline BasicStringPiece<Char> Tokenizer<Char>::iterator::operator*() {
-    return token;
+    return mToken;
 }
 
 template <typename Char>
 inline bool Tokenizer<Char>::iterator::operator==(const iterator& rhs) const {
     // We check equality here a bit differently.
     // We need to know that the addresses are the same.
-    return token.begin() == rhs.token.begin() && token.end() == rhs.token.end();
+    return mToken.begin() == rhs.mToken.begin() && mToken.end() == rhs.mToken.end() &&
+            mEnd == rhs.mEnd;
 }
 
 template <typename Char>
@@ -291,8 +294,8 @@
 
 template <typename Char>
 inline Tokenizer<Char>::iterator::iterator(BasicStringPiece<Char> s, Char sep,
-                                           BasicStringPiece<Char> tok) :
-        str(s), separator(sep), token(tok) {
+                                           BasicStringPiece<Char> tok, bool end) :
+        mStr(s), mSeparator(sep), mToken(tok), mEnd(end) {
 }
 
 template <typename Char>
@@ -307,8 +310,8 @@
 
 template <typename Char>
 inline Tokenizer<Char>::Tokenizer(BasicStringPiece<Char> str, Char sep) :
-        mBegin(++iterator(str, sep, BasicStringPiece<Char>(str.begin() - 1, 0))),
-        mEnd(str, sep, BasicStringPiece<Char>(str.end(), 0)) {
+        mBegin(++iterator(str, sep, BasicStringPiece<Char>(str.begin() - 1, 0), false)),
+        mEnd(str, sep, BasicStringPiece<Char>(str.end(), 0), true) {
 }
 
 inline uint16_t hostToDevice16(uint16_t value) {
diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp
index 9db9fb7..9208e07 100644
--- a/tools/aapt2/util/Util_test.cpp
+++ b/tools/aapt2/util/Util_test.cpp
@@ -101,6 +101,15 @@
     ASSERT_EQ(tokenizer.end(), iter);
 }
 
+TEST(UtilTest, TokenizeEmptyString) {
+    auto tokenizer = util::tokenize(StringPiece16(u""), u'|');
+    auto iter = tokenizer.begin();
+    ASSERT_NE(tokenizer.end(), iter);
+    ASSERT_EQ(StringPiece16(), *iter);
+    ++iter;
+    ASSERT_EQ(tokenizer.end(), iter);
+}
+
 TEST(UtilTest, TokenizeAtEnd) {
     auto tokenizer = util::tokenize(StringPiece16(u"one."), u'.');
     auto iter = tokenizer.begin();
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index 5db1bde..723e827 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -23,6 +23,7 @@
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.MockView;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
 import com.android.layoutlib.bridge.android.support.DrawerLayoutUtil;
@@ -126,6 +127,9 @@
             if (view == null) {
                 view = loadCustomView(name, attrs);
             }
+        } catch (InflateException e) {
+            // Don't catch the InflateException below as that results in hiding the real cause.
+            throw e;
         } catch (Exception e) {
             // Wrap the real exception in a ClassNotFoundException, so that the calling method
             // can deal with it.
@@ -154,23 +158,30 @@
                 }
                 ta.recycle();
             }
-            final Object lastContext = mConstructorArgs[0];
-            mConstructorArgs[0] = context;
-            // try to load the class from using the custom view loader
-            try {
-                view = loadCustomView(name, attrs);
-            } catch (Exception e2) {
-                // Wrap the real exception in an InflateException so that the calling
-                // method can deal with it.
-                InflateException exception = new InflateException();
-                if (!e2.getClass().equals(ClassNotFoundException.class)) {
-                    exception.initCause(e2);
-                } else {
-                    exception.initCause(e);
+            if (!(e.getCause() instanceof ClassNotFoundException)) {
+                // There is some unknown inflation exception in inflating a View that was found.
+                view = new MockView(context, attrs);
+                ((MockView) view).setText(name);
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e, null);
+            } else {
+                final Object lastContext = mConstructorArgs[0];
+                mConstructorArgs[0] = context;
+                // try to load the class from using the custom view loader
+                try {
+                    view = loadCustomView(name, attrs);
+                } catch (Exception e2) {
+                    // Wrap the real exception in an InflateException so that the calling
+                    // method can deal with it.
+                    InflateException exception = new InflateException();
+                    if (!e2.getClass().equals(ClassNotFoundException.class)) {
+                        exception.initCause(e2);
+                    } else {
+                        exception.initCause(e);
+                    }
+                    throw exception;
+                } finally {
+                    mConstructorArgs[0] = lastContext;
                 }
-                throw exception;
-            } finally {
-                mConstructorArgs[0] = lastContext;
             }
         }
 
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 7ee06f3..3c260a8 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -241,6 +241,13 @@
     }
 
     @Override
+    public void overridePendingAppTransitionMultiThumbFuture(
+            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback startedCallback,
+            boolean scaleUp) throws RemoteException {
+
+    }
+
+    @Override
     public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
             IRemoteCallback callback0, IRemoteCallback callback1, boolean scaleUp) {
         // TODO Auto-generated method stub
@@ -515,10 +522,23 @@
     }
 
     @Override
+    public int getDockedStackSide() throws RemoteException {
+        return 0;
+    }
+
+    @Override
+    public void setDockedStackResizing(boolean resizing) throws RemoteException {
+    }
+
+    @Override
     public void cancelTaskWindowTransition(int taskId) {
     }
 
     @Override
+    public void cancelTaskThumbnailTransition(int taskId) {
+    }
+
+    @Override
     public void endProlongedAnimations() {
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
index 44a9aad..d392f21 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
@@ -17,39 +17,90 @@
 package com.android.layoutlib.bridge;
 
 import android.content.Context;
-import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
 import android.widget.TextView;
 
 /**
  * Base class for mocked views.
- *
- * TODO: implement onDraw and draw a rectangle in a random color with the name of the class
- * (or better the id of the view).
+ * <p/>
+ * FrameLayout with a single TextView. Doesn't allow adding any other views to itself.
  */
-public class MockView extends TextView {
+public class MockView extends FrameLayout {
+
+    private final TextView mView;
+
+    public MockView(Context context) {
+        this(context, null);
+    }
 
     public MockView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
-    public MockView(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, 0);
+    public MockView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public MockView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-
-        setText(this.getClass().getSimpleName());
-        setTextColor(0xFF000000);
+        mView = new TextView(context, attrs);
+        mView.setTextColor(0xFF000000);
         setGravity(Gravity.CENTER);
+        setText(getClass().getSimpleName());
+        addView(mView);
+        setBackgroundColor(0xFF7F7F7F);
+    }
+
+    // Only allow adding one TextView.
+    @Override
+    public void addView(View child) {
+        if (child == mView) {
+            super.addView(child);
+        }
     }
 
     @Override
-    public void onDraw(Canvas canvas) {
-        canvas.drawARGB(0xFF, 0x7F, 0x7F, 0x7F);
+    public void addView(View child, int index) {
+        if (child == mView) {
+            super.addView(child, index);
+        }
+    }
 
-        super.onDraw(canvas);
+    @Override
+    public void addView(View child, int width, int height) {
+        if (child == mView) {
+            super.addView(child, width, height);
+        }
+    }
+
+    @Override
+    public void addView(View child, ViewGroup.LayoutParams params) {
+        if (child == mView) {
+            super.addView(child, params);
+        }
+    }
+
+    @Override
+    public void addView(View child, int index, ViewGroup.LayoutParams params) {
+        if (child == mView) {
+            super.addView(child, index, params);
+        }
+    }
+
+    // The following methods are called by the IDE via reflection, and should be considered part
+    // of the API.
+    // Historically, MockView used to be a textView and had these methods. Now, we simply delegate
+    // them to the contained textView.
+
+    public void setText(CharSequence text) {
+        mView.setText(text);
+    }
+
+    public void setGravity(int gravity) {
+        mView.setGravity(gravity);
     }
 }
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 4a5702d..0fcfa78 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
@@ -1371,6 +1371,18 @@
     }
 
     @Override
+    public File getDeviceEncryptedFilesDir() {
+        // pass
+        return null;
+    }
+
+    @Override
+    public File getCredentialEncryptedFilesDir() {
+        // pass
+        return null;
+    }
+
+    @Override
     public File getNoBackupFilesDir() {
         // pass
         return null;
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 c2d8d0c..3662573 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
@@ -48,7 +48,7 @@
 
     @Override
     public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6,
-            boolean b, Configuration configuration) throws RemoteException {
+            boolean b, Configuration configuration, Rect rect7) throws RemoteException {
         // pass for now.
     }
 
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 11bd15d..1ec0547 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
@@ -95,8 +95,8 @@
     }
 
     @Override
-    public void repositionChild(IWindow childWindow, int x, int y, long deferTransactionUntilFrame,
-            Rect outFrame) {
+    public void repositionChild(IWindow childWindow, int x, int y, int width, int height,
+            long deferTransactionUntilFrame, Rect outFrame) {
         // pass for now.
         return;
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index 868c6d3..b67afeb 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -16,10 +16,13 @@
 
 package com.android.layoutlib.bridge.bars;
 
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.SessionParams;
 import com.android.ide.common.rendering.api.StyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.resources.ResourceType;
@@ -45,6 +48,8 @@
 
     private Object mWindowDecorActionBar;
     private static final String WINDOW_ACTION_BAR_CLASS = "android.support.v7.internal.app.WindowDecorActionBar";
+    // This is used on v23.1.1 and later.
+    private static final String WINDOW_ACTION_BAR_CLASS_NEW = "android.support.v7.app.WindowDecorActionBar";
     private Class<?> mWindowActionBarClass;
 
     /**
@@ -70,14 +75,26 @@
         try {
             Class[] constructorParams = {View.class};
             Object[] constructorArgs = {getDecorContent()};
-            mWindowDecorActionBar = params.getLayoutlibCallback().loadView(WINDOW_ACTION_BAR_CLASS,
-                    constructorParams, constructorArgs);
+            LayoutlibCallback callback = params.getLayoutlibCallback();
+            // First try to load the class as was available before appcompat v23.1.1, without
+            // logging warnings.
+            try {
+                mWindowDecorActionBar = callback.loadClass(WINDOW_ACTION_BAR_CLASS,
+                        constructorParams, constructorArgs);
+            } catch (ClassNotFoundException ignore) {
+            }
+            if (mWindowDecorActionBar == null) {
+                // If failed, load the new class, while logging warnings.
+                mWindowDecorActionBar = callback.loadView(WINDOW_ACTION_BAR_CLASS_NEW,
+                        constructorParams, constructorArgs);
+            }
 
             mWindowActionBarClass = mWindowDecorActionBar == null ? null :
                     mWindowDecorActionBar.getClass();
             setupActionBar();
         } catch (Exception e) {
-            e.printStackTrace();
+            Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
+                    "Failed to load AppCompat ActionBar with unknown error.", e);
         }
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
index 9588035..80d7c68 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
@@ -21,6 +21,7 @@
 
 import android.graphics.BlendComposite;
 import android.graphics.BlendComposite.BlendingMode;
+import android.graphics.PorterDuff;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.PorterDuffColorFilter_Delegate;
 import android.graphics.PorterDuffXfermode_Delegate;
@@ -34,6 +35,8 @@
  */
 public final class PorterDuffUtility {
 
+    private static final int MODES_COUNT = Mode.values().length;
+
     // Make the class non-instantiable.
     private PorterDuffUtility() {
     }
@@ -43,12 +46,11 @@
      * {@link Mode#SRC_OVER} for invalid modes.
      */
     public static Mode getPorterDuffMode(int porterDuffMode) {
-        Mode[] values = Mode.values();
-        if (porterDuffMode >= 0 && porterDuffMode < values.length) {
-            return values[porterDuffMode];
+        if (porterDuffMode >= 0 && porterDuffMode < MODES_COUNT) {
+            return PorterDuff.intToMode(porterDuffMode);
         }
         Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null /*data*/);
+                String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null);
         assert false;
         return Mode.SRC_OVER;
     }